From 052c87005849d5406477607e352588b39fb96896 Mon Sep 17 00:00:00 2001 From: leoredivo <94771718+leoredivo@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:51:36 -0700 Subject: [PATCH 01/20] New function to kernel_disk_workload to allow new disk device location Added a parameter to kernel_disk_workload which allows users to change the disk device location. Maintained the previous way of setting a disk device as the default, however added a function to allow users to override this default --- .../gem5/components/boards/arm_board.py | 2 +- .../boards/experimental/lupv_board.py | 2 +- .../components/boards/kernel_disk_workload.py | 22 ++++++++++++++++++- .../gem5/components/boards/riscv_board.py | 2 +- .../gem5/components/boards/x86_board.py | 2 +- .../riscvmatched/riscvmatched_board.py | 2 +- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index b439edf970..82b7a39107 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -354,7 +354,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): ) @overrides(KernelDiskWorkload) - def get_disk_device(self): + def _get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index ad130b7273..cba50a1d56 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -539,7 +539,7 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): return ["console=ttyLIO0", "root={root_value}", "rw"] @overrides(KernelDiskWorkload) - def get_disk_device(self) -> str: + def set_default_disk_device(self) -> str: return "/dev/lda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index 15e0cdf303..79d55ba8b4 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -39,6 +39,7 @@ import os from pathlib import Path import m5 +from m5 import warn class KernelDiskWorkload: @@ -84,11 +85,25 @@ class KernelDiskWorkload: """ raise NotImplementedError - @abstractmethod def get_disk_device(self) -> str: """ Get the disk device, e.g., "/dev/sda", where the disk image is placed. + :returns: The disk device. + """ + if self._disk_device is None: + warn("No disk device set, ie where the disk image is located. Defaulting to board disk device") + return _get_default_disk_device() + else: + return self._disk_device + + + + @abstractmethod + def _get_default_disk_device(self) -> str: + """ + Set a default disk device, in case user does not specify a disk device. + :returns: The disk device. """ raise NotImplementedError @@ -139,6 +154,7 @@ class KernelDiskWorkload: kernel: KernelResource, disk_image: DiskImageResource, bootloader: Optional[BootloaderResource] = None, + _disk_device: Optional[str] = None, readfile: Optional[str] = None, readfile_contents: Optional[str] = None, kernel_args: Optional[List[str]] = None, @@ -171,6 +187,9 @@ class KernelDiskWorkload: # Abstract board. This function will not work otherwise. assert isinstance(self, AbstractBoard) + # Set the disk device + self._disk_device = _disk_device + # If we are setting a workload of this type, we need to run as a # full-system simulation. self._set_fullsystem(True) @@ -192,6 +211,7 @@ class KernelDiskWorkload: if bootloader is not None: self._bootloader = [bootloader.get_local_path()] + # Set the readfile. if readfile: self.readfile = readfile diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index 25f1fac562..d8020d1974 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -467,7 +467,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def get_disk_device(self): + def _get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/x86_board.py b/src/python/gem5/components/boards/x86_board.py index 04fec617c1..1a3b9fa1c8 100644 --- a/src/python/gem5/components/boards/x86_board.py +++ b/src/python/gem5/components/boards/x86_board.py @@ -296,7 +296,7 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload): ] @overrides(KernelDiskWorkload) - def get_disk_device(self): + def _get_default_disk_device(self): return "/dev/hda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 9ca95839f8..3411ea61be 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -539,7 +539,7 @@ class RISCVMatchedBoard( fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def get_disk_device(self): + def _get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) From cf1678f43f6faab30e2195040dbb235b08a350e9 Mon Sep 17 00:00:00 2001 From: Leo Redivo Date: Fri, 4 Aug 2023 13:08:41 -0700 Subject: [PATCH 02/20] misc: Fix pre-commit formatting issues Change-Id: I50e71cfc21d43c2c17da52cf2f40591599907548 --- .../gem5/components/boards/arm_board.py | 2 +- .../boards/experimental/lupv_board.py | 2 +- .../components/boards/kernel_disk_workload.py | 19 +++++++++---------- .../gem5/components/boards/riscv_board.py | 2 +- .../gem5/components/boards/x86_board.py | 2 +- .../riscvmatched/riscvmatched_board.py | 2 +- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index 82b7a39107..451bb8d7dc 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -354,7 +354,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): ) @overrides(KernelDiskWorkload) - def _get_default_disk_device(self): + def get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index cba50a1d56..f56a8804ed 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -539,7 +539,7 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): return ["console=ttyLIO0", "root={root_value}", "rw"] @overrides(KernelDiskWorkload) - def set_default_disk_device(self) -> str: + def get_default_disk_device(self) -> str: return "/dev/lda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index 79d55ba8b4..435de35f82 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -39,7 +39,7 @@ import os from pathlib import Path import m5 -from m5 import warn +from m5.util import inform class KernelDiskWorkload: @@ -92,15 +92,15 @@ class KernelDiskWorkload: :returns: The disk device. """ if self._disk_device is None: - warn("No disk device set, ie where the disk image is located. Defaulting to board disk device") - return _get_default_disk_device() - else: + self._disk_device = get_default_disk_device() + inform(f"Disk Device set to {self._disk_device}") + return self._disk_device + else: + inform(f"Disk Device set to {self._disk_device}") return self._disk_device - - @abstractmethod - def _get_default_disk_device(self) -> str: + def get_default_disk_device(self) -> str: """ Set a default disk device, in case user does not specify a disk device. @@ -154,7 +154,7 @@ class KernelDiskWorkload: kernel: KernelResource, disk_image: DiskImageResource, bootloader: Optional[BootloaderResource] = None, - _disk_device: Optional[str] = None, + disk_device: Optional[str] = None, readfile: Optional[str] = None, readfile_contents: Optional[str] = None, kernel_args: Optional[List[str]] = None, @@ -188,7 +188,7 @@ class KernelDiskWorkload: assert isinstance(self, AbstractBoard) # Set the disk device - self._disk_device = _disk_device + self._disk_device = disk_device # If we are setting a workload of this type, we need to run as a # full-system simulation. @@ -211,7 +211,6 @@ class KernelDiskWorkload: if bootloader is not None: self._bootloader = [bootloader.get_local_path()] - # Set the readfile. if readfile: self.readfile = readfile diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index d8020d1974..c12ad21e70 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -467,7 +467,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def _get_default_disk_device(self): + def get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/x86_board.py b/src/python/gem5/components/boards/x86_board.py index 1a3b9fa1c8..7541cdc415 100644 --- a/src/python/gem5/components/boards/x86_board.py +++ b/src/python/gem5/components/boards/x86_board.py @@ -296,7 +296,7 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload): ] @overrides(KernelDiskWorkload) - def _get_default_disk_device(self): + def get_default_disk_device(self): return "/dev/hda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 3411ea61be..5f26d0500d 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -539,7 +539,7 @@ class RISCVMatchedBoard( fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def _get_default_disk_device(self): + def get_default_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) From 576e8c1897f187ecdd69d8e753abbc97861b380a Mon Sep 17 00:00:00 2001 From: Leo Redivo Date: Fri, 11 Aug 2023 15:07:41 -0700 Subject: [PATCH 03/20] misc: Move inform to get_default_kernel_args() and fix formatting Change-Id: I788b630d811f8268da0e87923741cf9afdef0a3e --- src/python/gem5/components/boards/arm_board.py | 1 + .../boards/experimental/lupv_board.py | 13 +++++++++---- .../components/boards/kernel_disk_workload.py | 17 +++++++++-------- .../gem5/components/boards/riscv_board.py | 7 ++++++- src/python/gem5/components/boards/x86_board.py | 1 + .../prebuilt/riscvmatched/riscvmatched_board.py | 7 ++++++- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index 451bb8d7dc..ae4b84f859 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -386,6 +386,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): "lpj=19988480", "norandmaps", "root={root_value}", + "disk_device={disk_device}", "rw", f"mem={self.get_memory().get_size()}", ] diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index f56a8804ed..9136c5b797 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -534,14 +534,19 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtsFile(os.path.join(outdir, "device.dts")) fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) - @overrides(KernelDiskWorkload) - def get_default_kernel_args(self) -> List[str]: - return ["console=ttyLIO0", "root={root_value}", "rw"] - @overrides(KernelDiskWorkload) def get_default_disk_device(self) -> str: return "/dev/lda" + @overrides(KernelDiskWorkload) + def get_default_kernel_args(self) -> List[str]: + return [ + "console=ttyLIO0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] + @overrides(KernelDiskWorkload) def _add_disk_to_board(self, disk_image: AbstractResource) -> None: # Note: This must be called after set_workload because it looks for an diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index 435de35f82..ed12d33ac1 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -91,13 +91,13 @@ class KernelDiskWorkload: :returns: The disk device. """ - if self._disk_device is None: - self._disk_device = get_default_disk_device() - inform(f"Disk Device set to {self._disk_device}") - return self._disk_device - else: - inform(f"Disk Device set to {self._disk_device}") - return self._disk_device + to_return = ( + self._disk_device + if self._disk_device + else self.get_default_disk_device() + ) + assert to_return is not None + return to_return @abstractmethod def get_default_disk_device(self) -> str: @@ -201,7 +201,8 @@ class KernelDiskWorkload: self.workload.command_line = ( " ".join(kernel_args or self.get_default_kernel_args()) ).format( - root_value=self.get_default_kernel_root_val(disk_image=disk_image) + root_value=self.get_default_kernel_root_val(disk_image=disk_image), + disk_device=self.get_disk_device(), ) # Setting the bootloader information for ARM board. The current diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index c12ad21e70..c70216c52d 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -494,4 +494,9 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): @overrides(KernelDiskWorkload) def get_default_kernel_args(self) -> List[str]: - return ["console=ttyS0", "root={root_value}", "rw"] + return [ + "console=ttyS0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] diff --git a/src/python/gem5/components/boards/x86_board.py b/src/python/gem5/components/boards/x86_board.py index 7541cdc415..a0db8da10f 100644 --- a/src/python/gem5/components/boards/x86_board.py +++ b/src/python/gem5/components/boards/x86_board.py @@ -318,4 +318,5 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload): "console=ttyS0", "lpj=7999923", "root={root_value}", + "disk_device={disk_device}", ] diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 5f26d0500d..bd7d0acc27 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -566,7 +566,12 @@ class RISCVMatchedBoard( @overrides(KernelDiskWorkload) def get_default_kernel_args(self) -> List[str]: - return ["console=ttyS0", "root={root_value}", "rw"] + return [ + "console=ttyS0", + "root={root_value}", + "disk_device={disk_device}", + "rw", + ] @overrides(KernelDiskWorkload) def set_kernel_disk_workload( From 020bc05928bc6abc8ec3325c2039544badad9674 Mon Sep 17 00:00:00 2001 From: Leo Redivo Date: Thu, 14 Sep 2023 11:47:19 -0700 Subject: [PATCH 04/20] misc: moved logic of get_disk_device to workload.command_line Change-Id: I5313bb381d5d8983b050047849fae61ea7dfc63b --- .../components/boards/kernel_disk_workload.py | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index ed12d33ac1..1ca70f8f3f 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -39,7 +39,6 @@ import os from pathlib import Path import m5 -from m5.util import inform class KernelDiskWorkload: @@ -85,20 +84,6 @@ class KernelDiskWorkload: """ raise NotImplementedError - def get_disk_device(self) -> str: - """ - Get the disk device, e.g., "/dev/sda", where the disk image is placed. - - :returns: The disk device. - """ - to_return = ( - self._disk_device - if self._disk_device - else self.get_default_disk_device() - ) - assert to_return is not None - return to_return - @abstractmethod def get_default_disk_device(self) -> str: """ @@ -202,7 +187,11 @@ class KernelDiskWorkload: " ".join(kernel_args or self.get_default_kernel_args()) ).format( root_value=self.get_default_kernel_root_val(disk_image=disk_image), - disk_device=self.get_disk_device(), + disk_device=( + self._disk_device + if self._disk_device + else self.get_default_disk_device() + ), ) # Setting the bootloader information for ARM board. The current From 83374bdf999f96f933172e9c54e53d7ac97e60c0 Mon Sep 17 00:00:00 2001 From: Leo Redivo Date: Wed, 20 Sep 2023 15:28:49 -0700 Subject: [PATCH 05/20] misc: changed name get_default_disk_device to get_disk_device Change-Id: Ida9673445a4426ddedc8221010204bd2b71103a5 --- src/python/gem5/components/boards/arm_board.py | 2 +- src/python/gem5/components/boards/experimental/lupv_board.py | 2 +- src/python/gem5/components/boards/kernel_disk_workload.py | 2 +- src/python/gem5/components/boards/riscv_board.py | 2 +- src/python/gem5/components/boards/x86_board.py | 2 +- src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/python/gem5/components/boards/arm_board.py b/src/python/gem5/components/boards/arm_board.py index ae4b84f859..db215bd029 100644 --- a/src/python/gem5/components/boards/arm_board.py +++ b/src/python/gem5/components/boards/arm_board.py @@ -354,7 +354,7 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload): ) @overrides(KernelDiskWorkload) - def get_default_disk_device(self): + def get_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index 9136c5b797..51db66913a 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -535,7 +535,7 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def get_default_disk_device(self) -> str: + def get_disk_device(self) -> str: return "/dev/lda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index 1ca70f8f3f..c8c6e58878 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -85,7 +85,7 @@ class KernelDiskWorkload: raise NotImplementedError @abstractmethod - def get_default_disk_device(self) -> str: + def get_disk_device(self) -> str: """ Set a default disk device, in case user does not specify a disk device. diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index c70216c52d..d0000daffa 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -467,7 +467,7 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def get_default_disk_device(self): + def get_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/components/boards/x86_board.py b/src/python/gem5/components/boards/x86_board.py index a0db8da10f..01a0ac1f6b 100644 --- a/src/python/gem5/components/boards/x86_board.py +++ b/src/python/gem5/components/boards/x86_board.py @@ -296,7 +296,7 @@ class X86Board(AbstractSystemBoard, KernelDiskWorkload): ] @overrides(KernelDiskWorkload) - def get_default_disk_device(self): + def get_disk_device(self): return "/dev/hda" @overrides(KernelDiskWorkload) diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index bd7d0acc27..a4e639801d 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -539,7 +539,7 @@ class RISCVMatchedBoard( fdt.writeDtbFile(os.path.join(outdir, "device.dtb")) @overrides(KernelDiskWorkload) - def get_default_disk_device(self): + def get_disk_device(self): return "/dev/vda" @overrides(KernelDiskWorkload) From 98a6cd6ee245502fa2ec46acb9eab4691dec65f8 Mon Sep 17 00:00:00 2001 From: Leo Redivo Date: Wed, 4 Oct 2023 13:32:35 -0700 Subject: [PATCH 06/20] misc: changed call get_default_disk_device to get_disk_device Change-Id: I240da78a658208211ede6648547dfa4c971074a1 --- src/python/gem5/components/boards/kernel_disk_workload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/gem5/components/boards/kernel_disk_workload.py b/src/python/gem5/components/boards/kernel_disk_workload.py index c8c6e58878..72b143e6ff 100644 --- a/src/python/gem5/components/boards/kernel_disk_workload.py +++ b/src/python/gem5/components/boards/kernel_disk_workload.py @@ -190,7 +190,7 @@ class KernelDiskWorkload: disk_device=( self._disk_device if self._disk_device - else self.get_default_disk_device() + else self.get_disk_device() ), ) From 39c7e7d1eddc24ddddecd8abd7dbeae61f7959ac Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Wed, 4 Oct 2023 11:37:04 -0700 Subject: [PATCH 07/20] arch: Adding missing `override` to `PCState.set` As highlighed in this failing compiler test: https://github.com/gem5/gem5/actions/runs/6348223508/job/17389057995 Clang was failing when compiling "build/ALL/gem5.opt" due missing overrides in `PCState`'s "set" function. This was observed in Clang-14 and, stangely, Clang-8. Change-Id: I240c1087e8875fd07630e467e7452c62a5d14d5b --- src/arch/arm/pcstate.hh | 2 +- src/arch/generic/pcstate.hh | 4 ++-- src/arch/x86/pcstate.hh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/arm/pcstate.hh b/src/arch/arm/pcstate.hh index 7b75ed8184..a2f0463fab 100644 --- a/src/arch/arm/pcstate.hh +++ b/src/arch/arm/pcstate.hh @@ -92,7 +92,7 @@ class PCState : public GenericISA::UPCState<4> public: void - set(Addr val) + set(Addr val) override { Base::set(val); npc(val + (thumb() ? 2 : 4)); diff --git a/src/arch/generic/pcstate.hh b/src/arch/generic/pcstate.hh index 5c278a4233..25b3af69ea 100644 --- a/src/arch/generic/pcstate.hh +++ b/src/arch/generic/pcstate.hh @@ -489,7 +489,7 @@ class DelaySlotPCState : public SimplePCState void nnpc(Addr val) { _nnpc = val; } void - set(Addr val) + set(Addr val) override { Base::set(val); nnpc(val + 2 * InstWidth); @@ -563,7 +563,7 @@ class DelaySlotUPCState : public DelaySlotPCState } void - set(Addr val) + set(Addr val) override { Base::set(val); this->upc(0); diff --git a/src/arch/x86/pcstate.hh b/src/arch/x86/pcstate.hh index a0ed6ffe9f..95984d7a96 100644 --- a/src/arch/x86/pcstate.hh +++ b/src/arch/x86/pcstate.hh @@ -66,7 +66,7 @@ class PCState : public GenericISA::UPCState<8> } void - set(Addr val) + set(Addr val) override { Base::set(val); _size = 0; From 06bbc43b460a62597eadb55658f2bd77f42fcb00 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 5 Oct 2023 07:25:04 -0700 Subject: [PATCH 08/20] ext: Remove `std::binary_function` from DramPower `std::binary_function` was deprecated in C++11 and officially removed in CPP-17. This caused a compilation error on some systems. Fortunately it can be safely removed. It was unecessary. The commandItemSorter was compliant witih the `sort` regardless. Change-Id: I0d910e50c51cce2545dd89f618c99aef0fe8ab79 --- ext/drampower/src/CmdScheduler.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/drampower/src/CmdScheduler.h b/ext/drampower/src/CmdScheduler.h index 58efd279b1..1497304f54 100644 --- a/ext/drampower/src/CmdScheduler.h +++ b/ext/drampower/src/CmdScheduler.h @@ -84,8 +84,7 @@ class cmdScheduler { std::string name; physicalAddr PhysicalAddr; // sorting the commands according to their scheduling time. - struct commandItemSorter : public std::binary_function{ + struct commandItemSorter { bool operator()(const commandItem& lhs, const commandItem& rhs) const { From f75c0fca8a4e349a25f7e9503cc753dcb48c0212 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 5 Oct 2023 10:20:55 -0700 Subject: [PATCH 09/20] stdlib: Del comment stating SE mode limited to single thread This comment was left in the codebase in error. The `set_se_binary_workload` function works fine with multi-threaded applications. This hasn't been a restriction for some time. Change-Id: I1b1d27c86f8d9284659f62ae27d752bf5325e31b --- src/python/gem5/components/boards/se_binary_workload.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/gem5/components/boards/se_binary_workload.py b/src/python/gem5/components/boards/se_binary_workload.py index c62a1b67ea..cba268b2df 100644 --- a/src/python/gem5/components/boards/se_binary_workload.py +++ b/src/python/gem5/components/boards/se_binary_workload.py @@ -75,7 +75,6 @@ class SEBinaryWorkload: """Set up the system to run a specific binary. **Limitations** - * Only supports single threaded applications. * Dynamically linked executables are partially supported when the host ISA and the simulated ISA are the same. From 6a4b2bb0965a28d1428a60b867318e23511dd168 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Mon, 11 Sep 2023 09:22:26 -0500 Subject: [PATCH 10/20] dev-hsa,gpu-compute: Add timestamps to AMD HSA signals The AMD specific HSA signal contains start/end timestamps for dispatch packet completion signals. These are current always zero. These timestamp values are used for profiling in the ROCr runtime. Unfortunately, the GpuAgent::TranslateTime method in ROCr does not check for zero values before dividing, causing applications that use profiling to crash with SIGFPE. Profiling is used via hipEvents in the HACC application, so these should be supported in gem5. In order to handle writing the timestamp values, we need to DMA the values to memory before writing the completion signal. This changes the flow of the async completion signal write to be (1) read mailbox pointer (2) if valid, write the mailbox data, other skip to 4 (3) write mailbox data if pointer is valid (4) write timestamp values (5) write completion signal. The application will process the timestamp data as soon as the completion signal is received, so we need to ordering to ensure the DMA for timestamps was completed. HACC now runs to completion on GPUFS and has the same output was hardware. Change-Id: I09877cdff901d1402140f2c3bafea7605fa6554e --- src/dev/hsa/hsa_signal.hh | 6 ++ src/gpu-compute/gpu_command_processor.cc | 88 +++++++++++++++++------- src/gpu-compute/gpu_command_processor.hh | 4 ++ 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/src/dev/hsa/hsa_signal.hh b/src/dev/hsa/hsa_signal.hh index 6acbcb7e1b..7d1f316f04 100644 --- a/src/dev/hsa/hsa_signal.hh +++ b/src/dev/hsa/hsa_signal.hh @@ -69,6 +69,12 @@ typedef struct amd_signal_s uint32_t reserved3[2]; } amd_signal_t; +typedef struct +{ + uint64_t start_ts; + uint64_t end_ts; +} amd_event_t; + } // namespace gem5 #endif // DEV_HSA_HSA_SIGNAL_H diff --git a/src/gpu-compute/gpu_command_processor.cc b/src/gpu-compute/gpu_command_processor.cc index db69ad5cbd..ecc5f1d98b 100644 --- a/src/gpu-compute/gpu_command_processor.cc +++ b/src/gpu-compute/gpu_command_processor.cc @@ -248,6 +248,10 @@ GPUCommandProcessor::submitDispatchPkt(void *raw_pkt, uint32_t queue_id, initABI(task); ++dynamic_task_id; + + // The driver expects the start time to be in ns + Tick start_ts = curTick() / sim_clock::as_int::ns; + dispatchStartTime.insert({disp_pkt->completion_signal, start_ts}); } void @@ -280,16 +284,6 @@ GPUCommandProcessor::sendCompletionSignal(Addr signal_handle) void GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff) { - Addr value_addr = getHsaSignalValueAddr(signal_handle); - - uint64_t *signalValue = new uint64_t; - auto cb = new DmaVirtCallback( - [ = ] (const uint64_t &) - { updateHsaSignalData(value_addr, diff, signalValue); }); - dmaReadVirt(value_addr, sizeof(uint64_t), cb, (void *)signalValue); - DPRINTF(GPUCommandProc, "updateHsaSignalAsync reading value addr %lx\n", - value_addr); - Addr mailbox_addr = getHsaSignalMailboxAddr(signal_handle); uint64_t *mailboxValue = new uint64_t; auto cb2 = new DmaVirtCallback( @@ -300,20 +294,6 @@ GPUCommandProcessor::updateHsaSignalAsync(Addr signal_handle, int64_t diff) mailbox_addr); } -void -GPUCommandProcessor::updateHsaSignalData(Addr value_addr, int64_t diff, - uint64_t *prev_value) -{ - // Reuse the value allocated for the read - DPRINTF(GPUCommandProc, "updateHsaSignalData read %ld, writing %ld\n", - *prev_value, *prev_value + diff); - *prev_value += diff; - auto cb = new DmaVirtCallback( - [ = ] (const uint64_t &) - { updateHsaSignalDone(prev_value); }); - dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value); -} - void GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value) @@ -331,6 +311,20 @@ GPUCommandProcessor::updateHsaMailboxData(Addr signal_handle, dmaReadVirt(event_addr, sizeof(uint64_t), cb, (void *)mailbox_value); } else { delete mailbox_value; + + Addr ts_addr = signal_handle + offsetof(amd_signal_t, start_ts); + + amd_event_t *event_ts = new amd_event_t; + event_ts->start_ts = dispatchStartTime[signal_handle]; + event_ts->end_ts = curTick() / sim_clock::as_int::ns; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaEventTs(signal_handle, event_ts); }); + dmaWriteVirt(ts_addr, sizeof(amd_event_t), cb, (void *)event_ts); + DPRINTF(GPUCommandProc, "updateHsaMailboxData reading timestamp addr " + "%lx\n", ts_addr); + + dispatchStartTime.erase(signal_handle); } } @@ -346,6 +340,52 @@ GPUCommandProcessor::updateHsaEventData(Addr signal_handle, [ = ] (const uint64_t &) { updateHsaSignalDone(event_value); }, *event_value); dmaWriteVirt(mailbox_addr, sizeof(uint64_t), cb, &cb->dmaBuffer, 0); + + Addr ts_addr = signal_handle + offsetof(amd_signal_t, start_ts); + + amd_event_t *event_ts = new amd_event_t; + event_ts->start_ts = dispatchStartTime[signal_handle]; + event_ts->end_ts = curTick() / sim_clock::as_int::ns; + auto cb2 = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaEventTs(signal_handle, event_ts); }); + dmaWriteVirt(ts_addr, sizeof(amd_event_t), cb2, (void *)event_ts); + DPRINTF(GPUCommandProc, "updateHsaEventData reading timestamp addr %lx\n", + ts_addr); + + dispatchStartTime.erase(signal_handle); +} + +void +GPUCommandProcessor::updateHsaEventTs(Addr signal_handle, + amd_event_t *ts) +{ + delete ts; + + Addr value_addr = getHsaSignalValueAddr(signal_handle); + int64_t diff = -1; + + uint64_t *signalValue = new uint64_t; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaSignalData(value_addr, diff, signalValue); }); + dmaReadVirt(value_addr, sizeof(uint64_t), cb, (void *)signalValue); + DPRINTF(GPUCommandProc, "updateHsaSignalAsync reading value addr %lx\n", + value_addr); +} + +void +GPUCommandProcessor::updateHsaSignalData(Addr value_addr, int64_t diff, + uint64_t *prev_value) +{ + // Reuse the value allocated for the read + DPRINTF(GPUCommandProc, "updateHsaSignalData read %ld, writing %ld\n", + *prev_value, *prev_value + diff); + *prev_value += diff; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) + { updateHsaSignalDone(prev_value); }); + dmaWriteVirt(value_addr, sizeof(uint64_t), cb, (void *)prev_value); } void diff --git a/src/gpu-compute/gpu_command_processor.hh b/src/gpu-compute/gpu_command_processor.hh index 10407b9f93..f6783834eb 100644 --- a/src/gpu-compute/gpu_command_processor.hh +++ b/src/gpu-compute/gpu_command_processor.hh @@ -117,6 +117,7 @@ class GPUCommandProcessor : public DmaVirtDevice void updateHsaSignalDone(uint64_t *signal_value); void updateHsaMailboxData(Addr signal_handle, uint64_t *mailbox_value); void updateHsaEventData(Addr signal_handle, uint64_t *event_value); + void updateHsaEventTs(Addr signal_handle, amd_event_t *event_value); uint64_t functionalReadHsaSignal(Addr signal_handle); @@ -148,6 +149,9 @@ class GPUCommandProcessor : public DmaVirtDevice HSAPacketProcessor *hsaPP; TranslationGenPtr translate(Addr vaddr, Addr size) override; + // Keep track of start times for task dispatches. + std::unordered_map dispatchStartTime; + /** * Perform a DMA read of the read_dispatch_id_field_base_byte_offset * field, which follows directly after the read_dispatch_id (the read From 75a7f30dfb9ada69e8fdb35c54f0c3dd7d94164d Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Fri, 6 Oct 2023 13:02:31 -0500 Subject: [PATCH 11/20] dev-amdgpu: Implement GPU clock MMIOs The ROCr runtime uses a combination of HSA signal timestamps and hardware MMIOs to calculate profiling times. At the beginning of an application a timestamp is read from the GPU using MMIOs. The clock MMIOs reside in the GFX MMIO region, so a new AMDGPUGfx class is added to handle these MMIOs. The timestamp value is expected to be in nanoseconds, so we simply use the gem5 tick converted to ns. Change-Id: I7d1cba40d5042a7f7a81fd4d132402dc11b71bd4 --- src/dev/amdgpu/SConscript | 1 + src/dev/amdgpu/amdgpu_device.cc | 6 +++ src/dev/amdgpu/amdgpu_device.hh | 2 + src/dev/amdgpu/amdgpu_gfx.cc | 73 ++++++++++++++++++++++++++++++++ src/dev/amdgpu/amdgpu_gfx.hh | 75 +++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 src/dev/amdgpu/amdgpu_gfx.cc create mode 100644 src/dev/amdgpu/amdgpu_gfx.hh diff --git a/src/dev/amdgpu/SConscript b/src/dev/amdgpu/SConscript index 428d1c56bc..b8ba454d48 100644 --- a/src/dev/amdgpu/SConscript +++ b/src/dev/amdgpu/SConscript @@ -39,6 +39,7 @@ SimObject('AMDGPU.py', sim_objects=['AMDGPUDevice', 'AMDGPUInterruptHandler', tags='x86 isa') Source('amdgpu_device.cc', tags='x86 isa') +Source('amdgpu_gfx.cc', tags='x86 isa') Source('amdgpu_nbio.cc', tags='x86 isa') Source('amdgpu_vm.cc', tags='x86 isa') Source('interrupt_handler.cc', tags='x86 isa') diff --git a/src/dev/amdgpu/amdgpu_device.cc b/src/dev/amdgpu/amdgpu_device.cc index 5cc8df424f..1b81c4d0b2 100644 --- a/src/dev/amdgpu/amdgpu_device.cc +++ b/src/dev/amdgpu/amdgpu_device.cc @@ -379,6 +379,9 @@ AMDGPUDevice::readMMIO(PacketPtr pkt, Addr offset) case GRBM_BASE: gpuvm.readMMIO(pkt, aperture_offset >> GRBM_OFFSET_SHIFT); break; + case GFX_BASE: + gfx.readMMIO(pkt, aperture_offset); + break; case MMHUB_BASE: gpuvm.readMMIO(pkt, aperture_offset >> MMHUB_OFFSET_SHIFT); break; @@ -507,6 +510,9 @@ AMDGPUDevice::writeMMIO(PacketPtr pkt, Addr offset) case NBIO_BASE: nbio.writeMMIO(pkt, aperture_offset); break; + case GFX_BASE: + gfx.writeMMIO(pkt, aperture_offset); + break; default: DPRINTF(AMDGPUDevice, "Unknown MMIO aperture for %#x\n", offset); break; diff --git a/src/dev/amdgpu/amdgpu_device.hh b/src/dev/amdgpu/amdgpu_device.hh index 56ed2f4fa8..7f69ec19f6 100644 --- a/src/dev/amdgpu/amdgpu_device.hh +++ b/src/dev/amdgpu/amdgpu_device.hh @@ -36,6 +36,7 @@ #include "base/bitunion.hh" #include "dev/amdgpu/amdgpu_defines.hh" +#include "dev/amdgpu/amdgpu_gfx.hh" #include "dev/amdgpu/amdgpu_nbio.hh" #include "dev/amdgpu/amdgpu_vm.hh" #include "dev/amdgpu/memory_manager.hh" @@ -109,6 +110,7 @@ class AMDGPUDevice : public PciDevice * Blocks of the GPU */ AMDGPUNbio nbio; + AMDGPUGfx gfx; AMDGPUMemoryManager *gpuMemMgr; AMDGPUInterruptHandler *deviceIH; AMDGPUVM gpuvm; diff --git a/src/dev/amdgpu/amdgpu_gfx.cc b/src/dev/amdgpu/amdgpu_gfx.cc new file mode 100644 index 0000000000..3d5b274b86 --- /dev/null +++ b/src/dev/amdgpu/amdgpu_gfx.cc @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +#include "dev/amdgpu/amdgpu_gfx.hh" + +#include "mem/packet_access.hh" +#include "sim/core.hh" + +namespace gem5 +{ + +void +AMDGPUGfx::readMMIO(PacketPtr pkt, Addr offset) +{ + switch (offset) { + case AMDGPU_MM_RLC_GPU_CLOCK_COUNT_LSB: + pkt->setLE(captured_clock_count); + break; + case AMDGPU_MM_RLC_GPU_CLOCK_COUNT_MSB: + pkt->setLE(captured_clock_count >> 32); + break; + default: + break; + } +} + +void +AMDGPUGfx::writeMMIO(PacketPtr pkt, Addr offset) +{ + switch (offset) { + case AMDGPU_MM_RLC_CAPTURE_GPU_CLOCK_COUNT: + // Use gem5 Ticks in nanoseconds are the counter. The first capture + // is expected to return zero. + if (captured_clock_count == 1) { + captured_clock_count = 0; + } else { + captured_clock_count = curTick() / sim_clock::as_int::ns; + } + break; + default: + break; + } +} + +} // namespace gem5 diff --git a/src/dev/amdgpu/amdgpu_gfx.hh b/src/dev/amdgpu/amdgpu_gfx.hh new file mode 100644 index 0000000000..c32b8624cf --- /dev/null +++ b/src/dev/amdgpu/amdgpu_gfx.hh @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 HOLDER 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. + */ + +#ifndef __DEV_AMDGPU_AMDGPU_GFX_HH__ +#define __DEV_AMDGPU_AMDGPU_GFX_HH__ + +#include "base/types.hh" +#include "mem/packet.hh" + +/** + * MMIO offsets for GFX. This class handles MMIO reads/writes to the GFX_BASE + * aperture which are generally read/written by the gfx driver source here: + * + * drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c + * https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/blob/master/ + * drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c + * + * The MMIO addresses in the file are dword addresses. Here they are converted + * to byte addresses so gem5 does not need to shift the values. + */ + +// Registers used to read GPU clock count used in profiling +#define AMDGPU_MM_RLC_GPU_CLOCK_COUNT_LSB 0x13090 +#define AMDGPU_MM_RLC_GPU_CLOCK_COUNT_MSB 0x13094 +#define AMDGPU_MM_RLC_CAPTURE_GPU_CLOCK_COUNT 0x13098 + +namespace gem5 +{ + +class AMDGPUGfx +{ + public: + AMDGPUGfx() { } + + void readMMIO(PacketPtr pkt, Addr offset); + void writeMMIO(PacketPtr pkt, Addr offset); + + private: + /* + * GPU clock count at the time capture MMIO is received. + */ + uint64_t captured_clock_count = 1; +}; + +} // namespace gem5 + +#endif // __DEV_AMDGPU_AMDGPU_GFX_HH__ From edf9092feeb8b92c605fb1fc7a6e7f5486327509 Mon Sep 17 00:00:00 2001 From: David Schall Date: Sat, 7 Oct 2023 17:26:16 +0000 Subject: [PATCH 12/20] cpu: Restructure BTB - A new abstract BTB class is created to enable different BTB implementations. The new BTB class gets its own parameter and stats. - An enum is added to differentiate branch instruction types. This enum is used to enhance statistics and BPU management. - The existing BTB is moved into `simple_btb` as default. - An additional function is added to store the static instruction in the BTB. This function is used for the decoupled front-end. - Update configs to match new BTB parameters. Change-Id: I99b29a19a1b57e59ea2b188ed7d62a8b79426529 Signed-off-by: David Schall --- configs/common/cores/arm/HPI.py | 8 +- configs/common/cores/arm/O3_ARM_v7a.py | 8 +- configs/common/cores/arm/ex5_big.py | 8 +- src/cpu/pred/BranchPredictor.py | 57 +++++- src/cpu/pred/SConscript | 31 ++- src/cpu/pred/bpred_unit.cc | 17 +- src/cpu/pred/bpred_unit.hh | 22 ++- src/cpu/pred/branch_type.hh | 91 +++++++++ src/cpu/pred/btb.cc | 160 ++++++---------- src/cpu/pred/btb.hh | 136 +++++++------- src/cpu/pred/simple_btb.cc | 176 ++++++++++++++++++ src/cpu/pred/simple_btb.hh | 136 ++++++++++++++ .../riscvmatched/riscvmatched_core.py | 2 +- 13 files changed, 646 insertions(+), 206 deletions(-) create mode 100644 src/cpu/pred/branch_type.hh create mode 100644 src/cpu/pred/simple_btb.cc create mode 100644 src/cpu/pred/simple_btb.hh diff --git a/configs/common/cores/arm/HPI.py b/configs/common/cores/arm/HPI.py index d3d46054f1..cebd91cc72 100644 --- a/configs/common/cores/arm/HPI.py +++ b/configs/common/cores/arm/HPI.py @@ -1679,7 +1679,13 @@ class HPI_MMU(ArmMMU): dtb = ArmTLB(entry_type="data", size=256) +class HPI_BTB(SimpleBTB): + numEntries = 128 + tagBits = 18 + + class HPI_BP(TournamentBP): + btb = HPI_BTB() localPredictorSize = 64 localCtrBits = 2 localHistoryTableSize = 64 @@ -1687,8 +1693,6 @@ class HPI_BP(TournamentBP): globalCtrBits = 2 choicePredictorSize = 1024 choiceCtrBits = 2 - BTBEntries = 128 - BTBTagSize = 18 RASSize = 8 instShiftAmt = 2 diff --git a/configs/common/cores/arm/O3_ARM_v7a.py b/configs/common/cores/arm/O3_ARM_v7a.py index 6a1734235a..8c25b82496 100644 --- a/configs/common/cores/arm/O3_ARM_v7a.py +++ b/configs/common/cores/arm/O3_ARM_v7a.py @@ -107,14 +107,18 @@ class O3_ARM_v7a_FUP(FUPool): ] +class O3_ARM_v7a_BTB(SimpleBTB): + numEntries = 2048 + tagBits = 18 + + # Bi-Mode Branch Predictor class O3_ARM_v7a_BP(BiModeBP): + btb = O3_ARM_v7a_BTB() globalPredictorSize = 8192 globalCtrBits = 2 choicePredictorSize = 8192 choiceCtrBits = 2 - BTBEntries = 2048 - BTBTagSize = 18 RASSize = 16 instShiftAmt = 2 diff --git a/configs/common/cores/arm/ex5_big.py b/configs/common/cores/arm/ex5_big.py index 0d4d4903cf..3272ca4676 100644 --- a/configs/common/cores/arm/ex5_big.py +++ b/configs/common/cores/arm/ex5_big.py @@ -104,14 +104,18 @@ class ex5_big_FUP(FUPool): ] +class ex5_big_BTB(SimpleBTB): + numEntries = 4096 + tagBits = 18 + + # Bi-Mode Branch Predictor class ex5_big_BP(BiModeBP): + btb = ex5_big_BTB() globalPredictorSize = 4096 globalCtrBits = 2 choicePredictorSize = 1024 choiceCtrBits = 3 - BTBEntries = 4096 - BTBTagSize = 18 RASSize = 48 instShiftAmt = 2 diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py index d18ca3f821..3bf5e52ae0 100644 --- a/src/cpu/pred/BranchPredictor.py +++ b/src/cpu/pred/BranchPredictor.py @@ -1,3 +1,15 @@ +# Copyright (c) 2022-2023 The University of Edinburgh +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2012 Mark D. Hill and David A. Wood # Copyright (c) 2015 The University of Wisconsin # All rights reserved. @@ -25,10 +37,46 @@ # (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 m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * from m5.proxy import * +from m5.objects.ClockedObject import ClockedObject + + +class BranchType(Enum): + vals = [ + "NoBranch", + "Return", + "CallDirect", + "CallIndirect", # 'Call', + "DirectCond", + "DirectUncond", # 'Direct', + "IndirectCond", + "IndirectUncond", #'Indirect', + ] + + +class BranchTargetBuffer(ClockedObject): + type = "BranchTargetBuffer" + cxx_class = "gem5::branch_prediction::BranchTargetBuffer" + cxx_header = "cpu/pred/btb.hh" + abstract = True + + numThreads = Param.Unsigned(Parent.numThreads, "Number of threads") + + +class SimpleBTB(BranchTargetBuffer): + type = "SimpleBTB" + cxx_class = "gem5::branch_prediction::SimpleBTB" + cxx_header = "cpu/pred/simple_btb.hh" + + numEntries = Param.Unsigned(4096, "Number of BTB entries") + tagBits = Param.Unsigned(16, "Size of the BTB tags, in bits") + instShiftAmt = Param.Unsigned( + Parent.instShiftAmt, "Number of bits to shift instructions by" + ) + class IndirectPredictor(SimObject): type = "IndirectPredictor" @@ -63,11 +111,12 @@ class BranchPredictor(SimObject): abstract = True numThreads = Param.Unsigned(Parent.numThreads, "Number of threads") - BTBEntries = Param.Unsigned(4096, "Number of BTB entries") - BTBTagSize = Param.Unsigned(16, "Size of the BTB tags, in bits") - RASSize = Param.Unsigned(16, "RAS size") instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by") + RASSize = Param.Unsigned(16, "RAS size") + + btb = Param.BranchTargetBuffer(SimpleBTB(), "Branch target buffer (BTB)") + indirectBranchPred = Param.IndirectPredictor( SimpleIndirectPredictor(), "Indirect branch predictor, set to NULL to disable indirect predictions", diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript index f4b6870ec5..89054ba8e8 100644 --- a/src/cpu/pred/SConscript +++ b/src/cpu/pred/SConscript @@ -1,5 +1,17 @@ # -*- mode:python -*- +# Copyright (c) 2022-2023 The University of Edinburgh +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2006 The Regents of The University of Michigan # All rights reserved. # @@ -28,8 +40,12 @@ Import('*') -SimObject('BranchPredictor.py', sim_objects=[ - 'IndirectPredictor', 'SimpleIndirectPredictor', 'BranchPredictor', + +SimObject('BranchPredictor.py', + sim_objects=[ + 'BranchPredictor', + 'IndirectPredictor', 'SimpleIndirectPredictor', + 'BranchTargetBuffer', 'SimpleBTB', 'LocalBP', 'TournamentBP', 'BiModeBP', 'TAGEBase', 'TAGE', 'LoopPredictor', 'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB', 'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L', @@ -41,17 +57,16 @@ SimObject('BranchPredictor.py', sim_objects=[ 'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB', 'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB', 'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB', - 'MultiperspectivePerceptronTAGE8KB']) + 'MultiperspectivePerceptronTAGE8KB'], + enums=['BranchType']) -DebugFlag('Indirect') Source('bpred_unit.cc') Source('2bit_local.cc') -Source('btb.cc') Source('simple_indirect.cc') Source('indirect.cc') Source('ras.cc') Source('tournament.cc') -Source ('bi_mode.cc') +Source('bi_mode.cc') Source('tage_base.cc') Source('tage.cc') Source('loop_predictor.cc') @@ -66,6 +81,10 @@ Source('statistical_corrector.cc') Source('tage_sc_l.cc') Source('tage_sc_l_8KB.cc') Source('tage_sc_l_64KB.cc') +Source('btb.cc') +Source('simple_btb.cc') +DebugFlag('Indirect') +DebugFlag('BTB') DebugFlag('FreeList') DebugFlag('Branch') DebugFlag('Tage') diff --git a/src/cpu/pred/bpred_unit.cc b/src/cpu/pred/bpred_unit.cc index ed8d6c8b08..85cb7c9e2f 100644 --- a/src/cpu/pred/bpred_unit.cc +++ b/src/cpu/pred/bpred_unit.cc @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2012, 2014 ARM Limited - * Copyright (c) 2010 The University of Edinburgh + * Copyright (c) 2010,2022-2023 The University of Edinburgh * Copyright (c) 2012 Mark D. Hill and David A. Wood * All rights reserved * @@ -59,10 +59,7 @@ BPredUnit::BPredUnit(const Params ¶ms) : SimObject(params), numThreads(params.numThreads), predHist(numThreads), - BTB(params.BTBEntries, - params.BTBTagSize, - params.instShiftAmt, - params.numThreads), + btb(params.btb), RAS(numThreads), iPred(params.indirectBranchPred), stats(this), @@ -218,10 +215,13 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, if (inst->isDirectCtrl() || !iPred) { ++stats.BTBLookups; // Check BTB on direct branches - if (BTB.valid(pc.instAddr(), tid)) { + const PCStateBase * btb_target = btb->lookup(tid, + pc.instAddr(), + getBranchType(inst)); + if (btb_target) { ++stats.BTBHits; // If it's not a return, use the BTB to get target addr. - set(target, BTB.lookup(pc.instAddr(), tid)); + set(target, btb_target); DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s predicted " "target is %s\n", @@ -482,7 +482,8 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, hist_it->seqNum, hist_it->pc); ++stats.BTBUpdates; - BTB.update(hist_it->pc, corr_target, tid); + btb->update(tid, hist_it->pc, corr_target, + getBranchType(hist_it->inst)); } } else { //Actually not Taken diff --git a/src/cpu/pred/bpred_unit.hh b/src/cpu/pred/bpred_unit.hh index 4af1d876a8..1b10d44a7c 100644 --- a/src/cpu/pred/bpred_unit.hh +++ b/src/cpu/pred/bpred_unit.hh @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2012, 2014 ARM Limited - * Copyright (c) 2010 The University of Edinburgh + * Copyright (c) 2010,2022-2023 The University of Edinburgh * All rights reserved * * The license below extends only to copyright in the software and shall @@ -46,6 +46,7 @@ #include "base/statistics.hh" #include "base/types.hh" +#include "cpu/pred/branch_type.hh" #include "cpu/pred/btb.hh" #include "cpu/pred/indirect.hh" #include "cpu/pred/ras.hh" @@ -152,7 +153,14 @@ class BPredUnit : public SimObject * @param inst_PC The PC to look up. * @return Whether the BTB contains the given PC. */ - bool BTBValid(Addr instPC) { return BTB.valid(instPC, 0); } + bool BTBValid(ThreadID tid, Addr instPC) + { + return btb->valid(tid, instPC); + } + bool BTBValid(ThreadID tid, PCStateBase &instPC) + { + return BTBValid(tid, instPC.instAddr()); + } /** * Looks up a given PC in the BTB to get the predicted target. The PC may @@ -162,9 +170,9 @@ class BPredUnit : public SimObject * @return The address of the target of the branch. */ const PCStateBase * - BTBLookup(Addr inst_pc) + BTBLookup(ThreadID tid, PCStateBase &instPC) { - return BTB.lookup(inst_pc, 0); + return btb->lookup(tid, instPC.instAddr()); } /** @@ -189,10 +197,10 @@ class BPredUnit : public SimObject * @param target_PC The branch's target that will be added to the BTB. */ void - BTBUpdate(Addr instPC, const PCStateBase &target) + BTBUpdate(ThreadID tid, Addr instPC, const PCStateBase &target) { ++stats.BTBUpdates; - BTB.update(instPC, target, 0); + return btb->update(tid, instPC, target); } @@ -295,7 +303,7 @@ class BPredUnit : public SimObject std::vector predHist; /** The BTB. */ - DefaultBTB BTB; + BranchTargetBuffer* btb; /** The per-thread return address stack. */ std::vector RAS; diff --git a/src/cpu/pred/branch_type.hh b/src/cpu/pred/branch_type.hh new file mode 100644 index 0000000000..dcc6149a9b --- /dev/null +++ b/src/cpu/pred/branch_type.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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. + */ + +/* @file + * A helper for branch type information + */ + +#ifndef __CPU_PRED_BRANCH_TYPE_HH__ +#define __CPU_PRED_BRANCH_TYPE_HH__ + +#include "cpu/static_inst.hh" +#include "enums/BranchType.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +typedef enums::BranchType BranchType; + +inline BranchType getBranchType(StaticInstPtr inst) +{ + if (inst->isReturn()) { + return BranchType::Return; + } + + if (inst->isCall()) { + return inst->isDirectCtrl() + ? BranchType::CallDirect + : BranchType::CallIndirect; + } + + if (inst->isDirectCtrl()) { + return inst->isCondCtrl() + ? BranchType::DirectCond + : BranchType::DirectUncond; + } + + if (inst->isIndirectCtrl()) { + return inst->isCondCtrl() + ? BranchType::IndirectCond + : BranchType::IndirectUncond; + } + return BranchType::NoBranch; +} + +inline std::string toString(BranchType type) +{ + return std::string(enums::BranchTypeStrings[type]); +} + + +} // namespace branch_prediction +} // namespace gem5 + +#endif // __CPU_PRED_BRANCH_TYPE_HH__ diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc index 71afd45b9f..85d3e2c9bb 100644 --- a/src/cpu/pred/btb.cc +++ b/src/cpu/pred/btb.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -28,119 +40,59 @@ #include "cpu/pred/btb.hh" -#include "base/intmath.hh" -#include "base/trace.hh" -#include "debug/Fetch.hh" - namespace gem5 { namespace branch_prediction { -DefaultBTB::DefaultBTB(unsigned _numEntries, - unsigned _tagBits, - unsigned _instShiftAmt, - unsigned _num_threads) - : numEntries(_numEntries), - tagBits(_tagBits), - instShiftAmt(_instShiftAmt), - log2NumThreads(floorLog2(_num_threads)) +BranchTargetBuffer::BranchTargetBuffer(const Params ¶ms) + : ClockedObject(params), + numThreads(params.numThreads), + stats(this) { - DPRINTF(Fetch, "BTB: Creating BTB object.\n"); +} - if (!isPowerOf2(numEntries)) { - fatal("BTB entries is not a power of 2!"); +BranchTargetBuffer::BranchTargetBufferStats::BranchTargetBufferStats( + statistics::Group *parent) + : statistics::Group(parent), + ADD_STAT(lookups, statistics::units::Count::get(), + "Number of BTB lookups"), + ADD_STAT(misses, statistics::units::Count::get(), + "Number of BTB misses"), + ADD_STAT(updates, statistics::units::Count::get(), + "Number of BTB updates"), + ADD_STAT(mispredict, statistics::units::Count::get(), + "Number of BTB mispredictions. " + "No target found or target wrong."), + ADD_STAT(evictions, statistics::units::Count::get(), + "Number of BTB evictions") +{ + using namespace statistics; + lookups + .init(enums::Num_BranchType) + .flags(total | pdf); + + misses + .init(enums::Num_BranchType) + .flags(total | pdf); + + updates + .init(enums::Num_BranchType) + .flags(total | pdf); + + mispredict + .init(enums::Num_BranchType) + .flags(total | pdf); + + evictions.flags(nozero); + + for (int i = 0; i < enums::Num_BranchType; i++) { + lookups.subname(i, enums::BranchTypeStrings[i]); + misses.subname(i, enums::BranchTypeStrings[i]); + updates.subname(i, enums::BranchTypeStrings[i]); + mispredict.subname(i, enums::BranchTypeStrings[i]); } - - btb.resize(numEntries); - - for (unsigned i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } - - idxMask = numEntries - 1; - - tagMask = (1 << tagBits) - 1; - - tagShiftAmt = instShiftAmt + floorLog2(numEntries); -} - -void -DefaultBTB::reset() -{ - for (unsigned i = 0; i < numEntries; ++i) { - btb[i].valid = false; - } -} - -inline -unsigned -DefaultBTB::getIndex(Addr instPC, ThreadID tid) -{ - // Need to shift PC over by the word offset. - return ((instPC >> instShiftAmt) - ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) - & idxMask; -} - -inline -Addr -DefaultBTB::getTag(Addr instPC) -{ - return (instPC >> tagShiftAmt) & tagMask; -} - -bool -DefaultBTB::valid(Addr instPC, ThreadID tid) -{ - unsigned btb_idx = getIndex(instPC, tid); - - Addr inst_tag = getTag(instPC); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return true; - } else { - return false; - } -} - -// @todo Create some sort of return struct that has both whether or not the -// address is valid, and also the address. For now will just use addr = 0 to -// represent invalid entry. -const PCStateBase * -DefaultBTB::lookup(Addr inst_pc, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_pc, tid); - - Addr inst_tag = getTag(inst_pc); - - assert(btb_idx < numEntries); - - if (btb[btb_idx].valid - && inst_tag == btb[btb_idx].tag - && btb[btb_idx].tid == tid) { - return btb[btb_idx].target.get(); - } else { - return nullptr; - } -} - -void -DefaultBTB::update(Addr inst_pc, const PCStateBase &target, ThreadID tid) -{ - unsigned btb_idx = getIndex(inst_pc, tid); - - assert(btb_idx < numEntries); - - btb[btb_idx].tid = tid; - btb[btb_idx].valid = true; - set(btb[btb_idx].target, target); - btb[btb_idx].tag = getTag(inst_pc); } } // namespace branch_prediction diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh index 9213053d77..dd3e56a20f 100644 --- a/src/cpu/pred/btb.hh +++ b/src/cpu/pred/btb.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * @@ -29,9 +41,13 @@ #ifndef __CPU_PRED_BTB_HH__ #define __CPU_PRED_BTB_HH__ + #include "arch/generic/pcstate.hh" -#include "base/logging.hh" -#include "base/types.hh" +#include "base/statistics.hh" +#include "cpu/pred/branch_type.hh" +#include "cpu/static_inst.hh" +#include "params/BranchTargetBuffer.hh" +#include "sim/clocked_object.hh" namespace gem5 { @@ -39,93 +55,73 @@ namespace gem5 namespace branch_prediction { -class DefaultBTB +class BranchTargetBuffer : public ClockedObject { - private: - struct BTBEntry - { - /** The entry's tag. */ - Addr tag = 0; - - /** The entry's target. */ - std::unique_ptr target; - - /** The entry's thread id. */ - ThreadID tid; - - /** Whether or not the entry is valid. */ - bool valid = false; - }; - public: - /** Creates a BTB with the given number of entries, number of bits per - * tag, and instruction offset amount. - * @param numEntries Number of entries for the BTB. - * @param tagBits Number of bits for each tag in the BTB. - * @param instShiftAmt Offset amount for instructions to ignore alignment. - */ - DefaultBTB(unsigned numEntries, unsigned tagBits, - unsigned instShiftAmt, unsigned numThreads); + typedef BranchTargetBufferParams Params; + typedef enums::BranchType BranchType; - void reset(); + BranchTargetBuffer(const Params ¶ms); - /** Looks up an address in the BTB. Must call valid() first on the address. + virtual void memInvalidate() override = 0; + + /** Checks if a branch address is in the BTB. Intended as a quick check + * before calling lookup. Does not update statistics. * @param inst_PC The address of the branch to look up. - * @param tid The thread id. - * @return Returns the target of the branch. - */ - const PCStateBase *lookup(Addr instPC, ThreadID tid); - - /** Checks if a branch is in the BTB. - * @param inst_PC The address of the branch to look up. - * @param tid The thread id. * @return Whether or not the branch exists in the BTB. */ - bool valid(Addr instPC, ThreadID tid); + virtual bool valid(ThreadID tid, Addr instPC) = 0; + + /** Looks up an address in the BTB to get the target of the branch. + * @param inst_PC The address of the branch to look up. + * @param type Optional type of the branch to look up. + * @return The target of the branch or nullptr if the branch is not + * in the BTB. + */ + virtual const PCStateBase *lookup(ThreadID tid, Addr instPC, + BranchType type = BranchType::NoBranch) = 0; + + /** Looks up an address in the BTB and return the instruction + * information if existant. Does not update statistics. + * @param inst_PC The address of the branch to look up. + * @return Returns the target of the branch. + */ + virtual const StaticInstPtr getInst(ThreadID tid, Addr instPC) = 0; + /** Updates the BTB with the target of a branch. * @param inst_pc The address of the branch being updated. * @param target_pc The target address of the branch. - * @param tid The thread id. */ - void update(Addr inst_pc, const PCStateBase &target_pc, ThreadID tid); + virtual void update(ThreadID tid, Addr inst_pc, + const PCStateBase &target_pc, + BranchType type = BranchType::NoBranch, + StaticInstPtr inst = nullptr) = 0; - private: - /** Returns the index into the BTB, based on the branch's PC. - * @param inst_PC The branch to look up. - * @return Returns the index into the BTB. + /** Update BTB statistics */ - inline unsigned getIndex(Addr instPC, ThreadID tid); + virtual void incorrectTarget(Addr inst_pc, + BranchType type = BranchType::NoBranch) + { + stats.mispredict[type]++; + } - /** Returns the tag bits of a given address. - * @param inst_PC The branch's address. - * @return Returns the tag bits. - */ - inline Addr getTag(Addr instPC); + protected: + /** Number of the threads for which the branch history is maintained. */ + const unsigned numThreads; - /** The actual BTB. */ - std::vector btb; + struct BranchTargetBufferStats : public statistics::Group + { + BranchTargetBufferStats(statistics::Group *parent); - /** The number of entries in the BTB. */ - unsigned numEntries; + statistics::Vector lookups; + statistics::Vector misses; + statistics::Vector updates; + statistics::Vector mispredict; + statistics::Scalar evictions; - /** The index mask. */ - unsigned idxMask; + } stats; - /** The number of tag bits per entry. */ - unsigned tagBits; - - /** The tag mask. */ - unsigned tagMask; - - /** Number of bits to shift PC when calculating index. */ - unsigned instShiftAmt; - - /** Number of bits to shift PC when calculating tag. */ - unsigned tagShiftAmt; - - /** Log2 NumThreads used for hashing threadid */ - unsigned log2NumThreads; }; } // namespace branch_prediction diff --git a/src/cpu/pred/simple_btb.cc b/src/cpu/pred/simple_btb.cc new file mode 100644 index 0000000000..c78caac7a8 --- /dev/null +++ b/src/cpu/pred/simple_btb.cc @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * 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. + */ + +#include "cpu/pred/simple_btb.hh" + +#include "base/intmath.hh" +#include "base/trace.hh" +#include "debug/BTB.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +SimpleBTB::SimpleBTB(const SimpleBTBParams &p) + : BranchTargetBuffer(p), + numEntries(p.numEntries), + tagBits(p.tagBits), + instShiftAmt(p.instShiftAmt), + log2NumThreads(floorLog2(p.numThreads)) +{ + DPRINTF(BTB, "BTB: Creating BTB object.\n"); + + if (!isPowerOf2(numEntries)) { + fatal("BTB entries is not a power of 2!"); + } + + btb.resize(numEntries); + + for (unsigned i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } + + idxMask = numEntries - 1; + + tagMask = (1 << tagBits) - 1; + + tagShiftAmt = instShiftAmt + floorLog2(numEntries); +} + +void +SimpleBTB::memInvalidate() +{ + for (unsigned i = 0; i < numEntries; ++i) { + btb[i].valid = false; + } +} + +inline +unsigned +SimpleBTB::getIndex(Addr instPC, ThreadID tid) +{ + // Need to shift PC over by the word offset. + return ((instPC >> instShiftAmt) + ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads))) + & idxMask; +} + +inline +Addr +SimpleBTB::getTag(Addr instPC) +{ + return (instPC >> tagShiftAmt) & tagMask; +} + +SimpleBTB::BTBEntry * +SimpleBTB::findEntry(Addr instPC, ThreadID tid) +{ + unsigned btb_idx = getIndex(instPC, tid); + Addr inst_tag = getTag(instPC); + + assert(btb_idx < numEntries); + + if (btb[btb_idx].valid + && inst_tag == btb[btb_idx].tag + && btb[btb_idx].tid == tid) { + return &btb[btb_idx]; + } + + return nullptr; +} + +bool +SimpleBTB::valid(ThreadID tid, Addr instPC) +{ + BTBEntry *entry = findEntry(instPC, tid); + + return entry != nullptr; +} + +// @todo Create some sort of return struct that has both whether or not the +// address is valid, and also the address. For now will just use addr = 0 to +// represent invalid entry. +const PCStateBase * +SimpleBTB::lookup(ThreadID tid, Addr instPC, BranchType type) +{ + stats.lookups[type]++; + + BTBEntry *entry = findEntry(instPC, tid); + + if (entry) { + return entry->target.get(); + } + stats.misses[type]++; + return nullptr; +} + +const StaticInstPtr +SimpleBTB::getInst(ThreadID tid, Addr instPC) +{ + BTBEntry *entry = findEntry(instPC, tid); + + if (entry) { + return entry->inst; + } + return nullptr; +} + +void +SimpleBTB::update(ThreadID tid, Addr instPC, + const PCStateBase &target, + BranchType type, StaticInstPtr inst) +{ + unsigned btb_idx = getIndex(instPC, tid); + + assert(btb_idx < numEntries); + + stats.updates[type]++; + + btb[btb_idx].tid = tid; + btb[btb_idx].valid = true; + set(btb[btb_idx].target, target); + btb[btb_idx].tag = getTag(instPC); + btb[btb_idx].inst = inst; +} + +} // namespace branch_prediction +} // namespace gem5 diff --git a/src/cpu/pred/simple_btb.hh b/src/cpu/pred/simple_btb.hh new file mode 100644 index 0000000000..3c76890348 --- /dev/null +++ b/src/cpu/pred/simple_btb.hh @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2022-2023 The University of Edinburgh + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * 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. + */ + +#ifndef __CPU_PRED_SIMPLE_BTB_HH__ +#define __CPU_PRED_SIMPLE_BTB_HH__ + +#include "base/logging.hh" +#include "base/types.hh" +#include "cpu/pred/btb.hh" +#include "params/SimpleBTB.hh" + +namespace gem5 +{ + +namespace branch_prediction +{ + +class SimpleBTB : public BranchTargetBuffer +{ + public: + SimpleBTB(const SimpleBTBParams ¶ms); + + void memInvalidate() override; + bool valid(ThreadID tid, Addr instPC) override; + const PCStateBase *lookup(ThreadID tid, Addr instPC, + BranchType type = BranchType::NoBranch) override; + void update(ThreadID tid, Addr instPC, const PCStateBase &target_pc, + BranchType type = BranchType::NoBranch, + StaticInstPtr inst = nullptr) override; + const StaticInstPtr getInst(ThreadID tid, Addr instPC) override; + + + private: + struct BTBEntry + { + /** The entry's tag. */ + Addr tag = 0; + + /** The entry's target. */ + std::unique_ptr target; + + /** The entry's thread id. */ + ThreadID tid; + + /** Whether or not the entry is valid. */ + bool valid = false; + + /** Pointer to the static branch instruction at this address */ + StaticInstPtr inst = nullptr; + }; + + + /** Returns the index into the BTB, based on the branch's PC. + * @param inst_PC The branch to look up. + * @return Returns the index into the BTB. + */ + inline unsigned getIndex(Addr instPC, ThreadID tid); + + /** Returns the tag bits of a given address. + * @param inst_PC The branch's address. + * @return Returns the tag bits. + */ + inline Addr getTag(Addr instPC); + + /** Internal call to find an address in the BTB + * @param instPC The branch's address. + * @return Returns a pointer to the BTB entry if found, nullptr otherwise. + */ + BTBEntry *findEntry(Addr instPC, ThreadID tid); + + /** The actual BTB. */ + std::vector btb; + + /** The number of entries in the BTB. */ + unsigned numEntries; + + /** The index mask. */ + unsigned idxMask; + + /** The number of tag bits per entry. */ + unsigned tagBits; + + /** The tag mask. */ + unsigned tagMask; + + /** Number of bits to shift PC when calculating index. */ + unsigned instShiftAmt; + + /** Number of bits to shift PC when calculating tag. */ + unsigned tagShiftAmt; + + /** Log2 NumThreads used for hashing threadid */ + unsigned log2NumThreads; +}; + +} // namespace branch_prediction +} // namespace gem5 + +#endif // __CPU_PRED_SIMPLE_BTB_HH__ diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py index 4b8d2c1d32..ce265449c9 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_core.py @@ -95,7 +95,7 @@ class U74FUPool(MinorFUPool): class U74BP(TournamentBP): - BTBEntries = 32 + btb = SimpleBTB(numEntries=32) RASSize = 12 localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2 localPredictorSize = 16384 From 3b8c974456a8fe3a85687c56c31175b394e9dbbb Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 18 Sep 2023 09:50:32 +0100 Subject: [PATCH 13/20] configs: Refactor BaseSimpleSystem in devices.py We define a new parent (ClusterSystem) to model a system with one or more cpu clusters within it. The idea is to make this new base class reusable by SE systems/scripts as well (like starter_se.py) Change-Id: I1398d773813db565f6ad5ce62cb4c022cb12a55a Signed-off-by: Giacomo Travaglini Reviewed-by: Richard Cooper --- configs/example/arm/devices.py | 103 ++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/configs/example/arm/devices.py b/configs/example/arm/devices.py index 6c6474ca2b..03d0a84799 100644 --- a/configs/example/arm/devices.py +++ b/configs/example/arm/devices.py @@ -338,56 +338,15 @@ class FastmodelCluster(CpuCluster): pass -class BaseSimpleSystem(ArmSystem): - cache_line_size = 64 - - def __init__(self, mem_size, platform, **kwargs): - super(BaseSimpleSystem, self).__init__(**kwargs) - - self.voltage_domain = VoltageDomain(voltage="1.0V") - self.clk_domain = SrcClockDomain( - clock="1GHz", voltage_domain=Parent.voltage_domain - ) - - if platform is None: - self.realview = VExpress_GEM5_V1() - else: - self.realview = platform - - if hasattr(self.realview.gic, "cpu_addr"): - self.gic_cpu_addr = self.realview.gic.cpu_addr - - self.terminal = Terminal() - self.vncserver = VncServer() - - self.iobus = IOXBar() - # Device DMA -> MEM - self.mem_ranges = self.getMemRanges(int(Addr(mem_size))) +class ClusterSystem: + """ + Base class providing cpu clusters generation/handling methods to + SE/FS systems + """ + def __init__(self, **kwargs): self._clusters = [] - def getMemRanges(self, mem_size): - """ - Define system memory ranges. This depends on the physical - memory map provided by the realview platform and by the memory - size provided by the user (mem_size argument). - The method is iterating over all platform ranges until they cover - the entire user's memory requirements. - """ - mem_ranges = [] - for mem_range in self.realview._mem_regions: - size_in_range = min(mem_size, mem_range.size()) - - mem_ranges.append( - AddrRange(start=mem_range.start, size=size_in_range) - ) - - mem_size -= size_in_range - if mem_size == 0: - return mem_ranges - - raise ValueError("memory size too big for platform capabilities") - def numCpuClusters(self): return len(self._clusters) @@ -423,6 +382,56 @@ class BaseSimpleSystem(ArmSystem): cluster.connectMemSide(cluster_mem_bus) +class BaseSimpleSystem(ArmSystem, ClusterSystem): + cache_line_size = 64 + + def __init__(self, mem_size, platform, **kwargs): + ArmSystem.__init__(self, **kwargs) + ClusterSystem.__init__(self, **kwargs) + + self.voltage_domain = VoltageDomain(voltage="1.0V") + self.clk_domain = SrcClockDomain( + clock="1GHz", voltage_domain=Parent.voltage_domain + ) + + if platform is None: + self.realview = VExpress_GEM5_V1() + else: + self.realview = platform + + if hasattr(self.realview.gic, "cpu_addr"): + self.gic_cpu_addr = self.realview.gic.cpu_addr + + self.terminal = Terminal() + self.vncserver = VncServer() + + self.iobus = IOXBar() + # Device DMA -> MEM + self.mem_ranges = self.getMemRanges(int(Addr(mem_size))) + + def getMemRanges(self, mem_size): + """ + Define system memory ranges. This depends on the physical + memory map provided by the realview platform and by the memory + size provided by the user (mem_size argument). + The method is iterating over all platform ranges until they cover + the entire user's memory requirements. + """ + mem_ranges = [] + for mem_range in self.realview._mem_regions: + size_in_range = min(mem_size, mem_range.size()) + + mem_ranges.append( + AddrRange(start=mem_range.start, size=size_in_range) + ) + + mem_size -= size_in_range + if mem_size == 0: + return mem_ranges + + raise ValueError("memory size too big for platform capabilities") + + class SimpleSystem(BaseSimpleSystem): """ Meant to be used with the classic memory model From 7395b94c40a1b291e29f96b375448f799b969791 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 18 Sep 2023 09:51:47 +0100 Subject: [PATCH 14/20] configs: Add a SimpleSeSystem class to devices.py Change-Id: I9d120fbaf0c61c5a053163ec1e5f4f93c583df52 Signed-off-by: Giacomo Travaglini Reviewed-by: Richard Cooper --- configs/example/arm/devices.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/configs/example/arm/devices.py b/configs/example/arm/devices.py index 03d0a84799..7ceb3cd3bf 100644 --- a/configs/example/arm/devices.py +++ b/configs/example/arm/devices.py @@ -382,6 +382,30 @@ class ClusterSystem: cluster.connectMemSide(cluster_mem_bus) +class SimpleSeSystem(System, ClusterSystem): + """ + Example system class for syscall emulation mode + """ + + # Use a fixed cache line size of 64 bytes + cache_line_size = 64 + + def __init__(self, **kwargs): + System.__init__(self, **kwargs) + ClusterSystem.__init__(self, **kwargs) + # Create a voltage and clock domain for system components + self.voltage_domain = VoltageDomain(voltage="3.3V") + self.clk_domain = SrcClockDomain( + clock="1GHz", voltage_domain=self.voltage_domain + ) + + # Create the off-chip memory bus. + self.membus = SystemXBar() + + def connect(self): + self.system_port = self.membus.cpu_side_ports + + class BaseSimpleSystem(ArmSystem, ClusterSystem): cache_line_size = 64 From e35e2966c04f971326b76a630bef5c321cabcb57 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 18 Sep 2023 09:52:05 +0100 Subject: [PATCH 15/20] configs: Use devices.SimpleSeSystem in starter_se.py Change-Id: I742e280e7a2a4047ac4bb3d783a28ee97f461480 Signed-off-by: Giacomo Travaglini Reviewed-by: Richard Cooper --- configs/example/arm/starter_se.py | 95 +++++++++---------------------- 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/configs/example/arm/starter_se.py b/configs/example/arm/starter_se.py index f21f399675..9834487155 100644 --- a/configs/example/arm/starter_se.py +++ b/configs/example/arm/starter_se.py @@ -64,72 +64,6 @@ cpu_types = { } -class SimpleSeSystem(System): - """ - Example system class for syscall emulation mode - """ - - # Use a fixed cache line size of 64 bytes - cache_line_size = 64 - - def __init__(self, args, **kwargs): - super(SimpleSeSystem, self).__init__(**kwargs) - - # Setup book keeping to be able to use CpuClusters from the - # devices module. - self._clusters = [] - self._num_cpus = 0 - - # Create a voltage and clock domain for system components - self.voltage_domain = VoltageDomain(voltage="3.3V") - self.clk_domain = SrcClockDomain( - clock="1GHz", voltage_domain=self.voltage_domain - ) - - # Create the off-chip memory bus. - self.membus = SystemXBar() - - # Wire up the system port that gem5 uses to load the kernel - # and to perform debug accesses. - self.system_port = self.membus.cpu_side_ports - - # Add CPUs to the system. A cluster of CPUs typically have - # private L1 caches and a shared L2 cache. - self.cpu_cluster = devices.ArmCpuCluster( - self, - args.num_cores, - args.cpu_freq, - "1.2V", - *cpu_types[args.cpu], - tarmac_gen=args.tarmac_gen, - tarmac_dest=args.tarmac_dest, - ) - - # Create a cache hierarchy (unless we are simulating a - # functional CPU in atomic memory mode) for the CPU cluster - # and connect it to the shared memory bus. - if self.cpu_cluster.memory_mode() == "timing": - self.cpu_cluster.addL1() - self.cpu_cluster.addL2(self.cpu_cluster.clk_domain) - self.cpu_cluster.connectMemSide(self.membus) - - # Tell gem5 about the memory mode used by the CPUs we are - # simulating. - self.mem_mode = self.cpu_cluster.memory_mode() - - def numCpuClusters(self): - return len(self._clusters) - - def addCpuCluster(self, cpu_cluster): - assert cpu_cluster not in self._clusters - assert len(cpu_cluster) > 0 - self._clusters.append(cpu_cluster) - self._num_cpus += len(cpu_cluster) - - def numCpus(self): - return self._num_cpus - - def get_processes(cmd): """Interprets commands to run and returns a list of processes""" @@ -150,7 +84,31 @@ def get_processes(cmd): def create(args): """Create and configure the system object.""" - system = SimpleSeSystem(args) + cpu_class = cpu_types[args.cpu][0] + mem_mode = cpu_class.memory_mode() + # Only simulate caches when using a timing CPU (e.g., the HPI model) + want_caches = True if mem_mode == "timing" else False + + system = devices.SimpleSeSystem( + mem_mode=mem_mode, + ) + + # Add CPUs to the system. A cluster of CPUs typically have + # private L1 caches and a shared L2 cache. + system.cpu_cluster = devices.ArmCpuCluster( + system, + args.num_cores, + args.cpu_freq, + "1.2V", + *cpu_types[args.cpu], + tarmac_gen=args.tarmac_gen, + tarmac_dest=args.tarmac_dest, + ) + + # Create a cache hierarchy for the cluster. We are assuming that + # clusters have core-private L1 caches and an L2 that's shared + # within the cluster. + system.addCaches(want_caches, last_cache_level=2) # Tell components about the expected physical memory ranges. This # is, for example, used by the MemConfig helper to determine where @@ -160,6 +118,9 @@ def create(args): # Configure the off-chip memory system. MemConfig.config_mem(args, system) + # Wire up the system's memory system + system.connect() + # Parse the command line and get a list of Processes instances # that we can pass to gem5. processes = get_processes(args.commands_to_run) From 1a5dee0f0f9839f6c47f99d77a9fab823fd94fe4 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 13 Sep 2023 20:24:02 +0100 Subject: [PATCH 16/20] configs: Add an elastic-trace-generating CPU According to the original paper [1] the elastic trace generation process requires a cpu with a big number of entries in the ROB, LQ and SQ, so that there are no stalls due to resource limitation. At the moment these numbers are copy pasted from the CpuConfig.config_etrace method [2]. [1]: https://ieeexplore.ieee.org/document/7818336 [2]: https://github.com/gem5/gem5/blob/stable/\ configs/common/CpuConfig.py#L40 Change-Id: I00fde49e5420e420a4eddb7b49de4b74360348c9 Signed-off-by: Giacomo Travaglini Reviewed-by: Richard Cooper --- configs/common/cores/arm/O3_ARM_Etrace.py | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 configs/common/cores/arm/O3_ARM_Etrace.py diff --git a/configs/common/cores/arm/O3_ARM_Etrace.py b/configs/common/cores/arm/O3_ARM_Etrace.py new file mode 100644 index 0000000000..20870a0b7a --- /dev/null +++ b/configs/common/cores/arm/O3_ARM_Etrace.py @@ -0,0 +1,58 @@ +# Copyright (c) 2012, 2017-2018, 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# 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 m5.objects import * +from .O3_ARM_v7a import O3_ARM_v7a_3 + +# O3_ARM_v7a_3 adapted to generate elastic traces +class O3_ARM_v7a_3_Etrace(O3_ARM_v7a_3): + # Make the number of entries in the ROB, LQ and SQ very + # large so that there are no stalls due to resource + # limitation as such stalls will get captured in the trace + # as compute delay. For replay, ROB, LQ and SQ sizes are + # modelled in the Trace CPU. + numROBEntries = 512 + LQEntries = 128 + SQEntries = 128 + + def attach_probe_listener(self, inst_trace_file, data_trace_file): + # Attach the elastic trace probe listener. Set the protobuf trace + # file names. Set the dependency window size equal to the cpu it + # is attached to. + self.traceListener = m5.objects.ElasticTrace( + instFetchTraceFile=inst_trace_file, + dataDepTraceFile=data_trace_file, + depWindowSize=3 * self.numROBEntries, + ) From 4c4615523f1367bef4ea143072f202c5c0b48b81 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 13 Sep 2023 20:27:58 +0100 Subject: [PATCH 17/20] configs: Add an example elastic-trace-generating script The new script will automatically use the newly defined O3_ARM_v7a_3_Etrace CPU to run a simple SE simulation while generating elastic trace files. The script is based on starter_se.py, but contains the following limitations: 1) No L2 cache as it might affect computational delay calculations 2) Supporting SimpleMemory only with minimal memory latency There restrictions were imported by the existing elastic trace generation logic in the common library (collected by grepping elastic_trace_en) [1][2][3] Example usage: build/ARM/gem5.opt configs/example/arm/etrace_se.py \ --inst-trace-file [INSTRUCTION TRACE] \ --data-trace-file [DATA TRACE] \ [WORKLOAD] [1]: https://github.com/gem5/gem5/blob/stable/\ configs/common/MemConfig.py#L191 [2]: https://github.com/gem5/gem5/blob/stable/\ configs/common/MemConfig.py#L232 [3]: https://github.com/gem5/gem5/blob/stable/\ configs/common/CacheConfig.py#L130 Change-Id: I021fc84fa101113c5c2f0737d50a930bb4750f76 Signed-off-by: Giacomo Travaglini Reviewed-by: Richard Cooper --- configs/example/arm/etrace_se.py | 191 +++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 configs/example/arm/etrace_se.py diff --git a/configs/example/arm/etrace_se.py b/configs/example/arm/etrace_se.py new file mode 100644 index 0000000000..8fa971ff84 --- /dev/null +++ b/configs/example/arm/etrace_se.py @@ -0,0 +1,191 @@ +# Copyright (c) 2016-2017, 2022-2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# 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 m5 +from m5.util import addToPath +from m5.objects import * +import argparse +import shlex + +m5.util.addToPath("../..") + +from common import ObjectList + +import devices + + +def get_processes(cmd): + """Interprets commands to run and returns a list of processes""" + + cwd = os.getcwd() + multiprocesses = [] + for idx, c in enumerate(cmd): + argv = shlex.split(c) + + process = Process(pid=100 + idx, cwd=cwd, cmd=argv, executable=argv[0]) + process.gid = os.getgid() + + print("info: %d. command and arguments: %s" % (idx + 1, process.cmd)) + multiprocesses.append(process) + + return multiprocesses + + +def create(args): + """Create and configure the system object.""" + + system = devices.SimpleSeSystem( + mem_mode="timing", + ) + + # Add CPUs to the system. A cluster of CPUs typically have + # private L1 caches and a shared L2 cache. + system.cpu_cluster = devices.ArmCpuCluster( + system, + args.num_cores, + args.cpu_freq, + "1.2V", + ObjectList.cpu_list.get("O3_ARM_v7a_3_Etrace"), + devices.L1I, + devices.L1D, + devices.L2, + ) + + # Attach the elastic trace probe listener to every CPU in the cluster + for cpu in system.cpu_cluster: + cpu.attach_probe_listener(args.inst_trace_file, args.data_trace_file) + + # As elastic trace generation is enabled, make sure the memory system is + # minimal so that compute delays do not include memory access latencies. + # Configure the compulsory L1 caches for the O3CPU, do not configure + # any more caches. + system.addCaches(True, last_cache_level=1) + + # For elastic trace, over-riding Simple Memory latency to 1ns." + system.memory = SimpleMemory( + range=AddrRange(start=0, size=args.mem_size), + latency="1ns", + port=system.membus.mem_side_ports, + ) + + # Parse the command line and get a list of Processes instances + # that we can pass to gem5. + processes = get_processes(args.commands_to_run) + if len(processes) != args.num_cores: + print( + "Error: Cannot map %d command(s) onto %d CPU(s)" + % (len(processes), args.num_cores) + ) + sys.exit(1) + + system.workload = SEWorkload.init_compatible(processes[0].executable) + + # Assign one workload to each CPU + for cpu, workload in zip(system.cpu_cluster.cpus, processes): + cpu.workload = workload + + return system + + +def main(): + parser = argparse.ArgumentParser(epilog=__doc__) + + parser.add_argument( + "commands_to_run", + metavar="command(s)", + nargs="+", + help="Command(s) to run", + ) + parser.add_argument( + "--inst-trace-file", + action="store", + type=str, + help="""Instruction fetch trace file input to + Elastic Trace probe in a capture simulation and + Trace CPU in a replay simulation""", + default="fetchtrace.proto.gz", + ) + parser.add_argument( + "--data-trace-file", + action="store", + type=str, + help="""Data dependency trace file input to + Elastic Trace probe in a capture simulation and + Trace CPU in a replay simulation""", + default="deptrace.proto.gz", + ) + parser.add_argument("--cpu-freq", type=str, default="4GHz") + parser.add_argument( + "--num-cores", type=int, default=1, help="Number of CPU cores" + ) + parser.add_argument( + "--mem-size", + action="store", + type=str, + default="2GB", + help="Specify the physical memory size", + ) + + args = parser.parse_args() + + # Create a single root node for gem5's object hierarchy. There can + # only exist one root node in the simulator at any given + # time. Tell gem5 that we want to use syscall emulation mode + # instead of full system mode. + root = Root(full_system=False) + + # Populate the root node with a system. A system corresponds to a + # single node with shared memory. + root.system = create(args) + + # Instantiate the C++ object hierarchy. After this point, + # SimObjects can't be instantiated anymore. + m5.instantiate() + + # Start the simulator. This gives control to the C++ world and + # starts the simulator. The returned event tells the simulation + # script why the simulator exited. + event = m5.simulate() + + # Print the reason for the simulation exit. Some exit codes are + # requests for service (e.g., checkpoints) from the simulation + # script. We'll just ignore them here and exit. + print(f"{event.getCause()} ({event.getCode()}) @ {m5.curTick()}") + + +if __name__ == "__m5_main__": + main() From 5b09777011dd03a17431397b98adc321f1f366bb Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 9 Oct 2023 13:16:52 -0700 Subject: [PATCH 18/20] misc,python: Add `pre-commit-hook-yamlfmt` to pre-commit This automatically formats .yaml files. By deault has the following parameters: * `mapping`: 4 spaces. * `sequence`: 6 spaces. * `offset`: 4 spaces. * `colons`: do not align top-level colons. * `width`: None. Change-Id: Iee5194cd57b7b162fd7e33aa6852b64c5578a3d2 --- .pre-commit-config.yaml | 97 ++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 37b1acbbea..367a7c09d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,4 @@ +--- # Copyright (c) 2022 Arm Limited # All rights reserved. # @@ -33,57 +34,61 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -minimum_pre_commit_version: "2.18" +minimum_pre_commit_version: '2.18' default_language_version: - python: python3 + python: python3 exclude: | - (?x)^( - ext/(?!testlib/).*| - build/.*| - src/systemc/ext/.*| - src/systemc/tests/.*/.*| - src/python/m5/ext/pyfdt/.*| - tests/.*/ref/.* - )$ + (?x)^( + ext/(?!testlib/).*| + build/.*| + src/systemc/ext/.*| + src/systemc/tests/.*/.*| + src/python/m5/ext/pyfdt/.*| + tests/.*/ref/.* + )$ default_stages: [commit] repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-json - - id: check-yaml - - id: check-added-large-files - - id: mixed-line-ending - args: [--fix=lf] - - id: check-case-conflict -- repo: https://github.com/psf/black - rev: 22.6.0 - hooks: - - id: black -- repo: local - hooks: - - id: gem5-style-checker - name: gem5 style checker - entry: util/git-pre-commit.py - always_run: true - exclude: ".*" - language: system - description: 'The gem5 style checker hook.' - - id: gem5-commit-msg-checker - name: gem5 commit msg checker - entry: ext/git-commit-msg - language: system - stages: [commit-msg] - description: 'The gem5 commit message checker hook.' - - id: gerrit-commit-msg-job - name: gerrit commit message job - entry: util/gerrit-commit-msg-hook - language: system - stages: [commit-msg] - description: 'Adds Change-ID to the commit message. Needed by Gerrit.' + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-json + - id: check-yaml + - id: check-added-large-files + - id: mixed-line-ending + args: [--fix=lf] + - id: check-case-conflict + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt + rev: 0.2.3 + hooks: + - id: yamlfmt + - repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black + - repo: local + hooks: + - id: gem5-style-checker + name: gem5 style checker + entry: util/git-pre-commit.py + always_run: true + exclude: .* + language: system + description: The gem5 style checker hook. + - id: gem5-commit-msg-checker + name: gem5 commit msg checker + entry: ext/git-commit-msg + language: system + stages: [commit-msg] + description: The gem5 commit message checker hook. + - id: gerrit-commit-msg-job + name: gerrit commit message job + entry: util/gerrit-commit-msg-hook + language: system + stages: [commit-msg] + description: Adds Change-ID to the commit message. Needed by Gerrit. From fa8c9414b282832b2c963f8c6eafba42f05a264b Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 9 Oct 2023 13:20:25 -0700 Subject: [PATCH 19/20] misc,python: Run `pre-commit run --all-files` This applies the automatical formatting to the .yaml files. Change-Id: I10d067ba65722aca8aaf64a62b42ae57de468e75 --- .github/workflows/ci-tests.yaml | 261 +++++++------- .github/workflows/compiler-tests.yaml | 77 +++-- .github/workflows/daily-tests.yaml | 472 +++++++++++++------------- .github/workflows/docker-build.yaml | 79 ++--- .github/workflows/gpu-tests.yaml | 93 ++--- .github/workflows/utils.yaml | 26 +- .github/workflows/weekly-tests.yaml | 174 +++++----- MAINTAINERS.yaml | 299 ++++++++-------- util/dockerfiles/docker-compose.yaml | 1 + 9 files changed, 745 insertions(+), 737 deletions(-) diff --git a/.github/workflows/ci-tests.yaml b/.github/workflows/ci-tests.yaml index 5a92422e79..2a61c17209 100644 --- a/.github/workflows/ci-tests.yaml +++ b/.github/workflows/ci-tests.yaml @@ -1,105 +1,106 @@ +--- # This workflow runs after a pull-request has been approved by a reviewer. name: CI Tests on: - pull_request: - types: [opened, edited, synchronize, ready_for_review] + pull_request: + types: [opened, edited, synchronize, ready_for_review] concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true jobs: - pre-commit: + pre-commit: # runs on github hosted runner - runs-on: ubuntu-22.04 - if: github.event.pull_request.draft == false - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - - uses: pre-commit/action@v3.0.0 + runs-on: ubuntu-22.04 + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 # ensures we have a change-id in every commit, needed for gerrit - check-for-change-id: + check-for-change-id: # runs on github hosted runner - runs-on: ubuntu-22.04 - if: github.event.pull_request.draft == false - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Check for Change-Id - run: | - # loop through all the commits in the pull request - for commit in $(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}); do - git checkout $commit - if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ") - then - # passes as long as at least one change-id exists in the pull request - exit 0 - fi - done - # if we reach this part, none of the commits had a change-id - echo "None of the commits in this pull request contains a Change-ID, which we require for any changes made to gem5. "\ - "To automatically insert one, run the following:\n f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; "\ - "curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f\n Then amend the commit with git commit --amend --no-edit, and update your pull request." - exit 1 + runs-on: ubuntu-22.04 + if: github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Check for Change-Id + run: | + # loop through all the commits in the pull request + for commit in $(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}); do + git checkout $commit + if (git log -1 --pretty=format:"%B" | grep -q "Change-Id: ") + then + # passes as long as at least one change-id exists in the pull request + exit 0 + fi + done + # if we reach this part, none of the commits had a change-id + echo "None of the commits in this pull request contains a Change-ID, which we require for any changes made to gem5. "\ + "To automatically insert one, run the following:\n f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; "\ + "curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f\n Then amend the commit with git commit --amend --no-edit, and update your pull request." + exit 1 - unittests-all-opt: - runs-on: [self-hosted, linux, x64, run] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id] # only runs if pre-commit and change-id passes - timeout-minutes: 60 - steps: - - uses: actions/checkout@v3 - - name: CI Unittests - working-directory: ${{ github.workspace }} - run: scons build/ALL/unittests.opt -j $(nproc) - - run: echo "This job's status is ${{ job.status }}." + unittests-all-opt: + runs-on: [self-hosted, linux, x64, run] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id] # only runs if pre-commit and change-id passes + timeout-minutes: 60 + steps: + - uses: actions/checkout@v3 + - name: CI Unittests + working-directory: ${{ github.workspace }} + run: scons build/ALL/unittests.opt -j $(nproc) + - run: echo "This job's status is ${{ job.status }}." - testlib-quick-matrix: - runs-on: [self-hosted, linux, x64, run] - if: github.event.pull_request.draft == false + testlib-quick-matrix: + runs-on: [self-hosted, linux, x64, run] + if: github.event.pull_request.draft == false # In order to make sure the environment is exactly the same, we run in # the same container we use to build gem5 and run the testlib tests. This - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id] - steps: - - uses: actions/checkout@v3 + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id] + steps: + - uses: actions/checkout@v3 # Unfortunately the 'ubunutu-latest' image doesn't have jq installed. # We therefore need to install it as a step here. - - name: Install jq - run: apt install -y jq + - name: Install jq + run: apt install -y jq - - name: Get directories for testlib-quick - working-directory: "${{ github.workspace }}/tests" - id: dir-matrix - run: echo "test-dirs-matrix=$(find gem5/* -type d -maxdepth 0 | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT + - name: Get directories for testlib-quick + working-directory: ${{ github.workspace }}/tests + id: dir-matrix + run: echo "test-dirs-matrix=$(find gem5/* -type d -maxdepth 0 | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT - - name: Get the build targets for testlib-quick-gem5-builds - working-directory: "${{ github.workspace }}/tests" - id: build-matrix - run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT + - name: Get the build targets for testlib-quick-gem5-builds + working-directory: ${{ github.workspace }}/tests + id: build-matrix + run: echo "build-matrix=$(./main.py list --build-targets -q | jq -ncR '[inputs]')" >>$GITHUB_OUTPUT - outputs: - build-matrix: ${{ steps.build-matrix.outputs.build-matrix }} - test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }} + outputs: + build-matrix: ${{ steps.build-matrix.outputs.build-matrix }} + test-dirs-matrix: ${{ steps.dir-matrix.outputs.test-dirs-matrix }} - testlib-quick-gem5-builds: - runs-on: [self-hosted, linux, x64, build] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id, testlib-quick-matrix] - strategy: - matrix: - build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }} - steps: - - uses: actions/checkout@v3 - - name: Build gem5 - run: scons ${{ matrix.build-target }} -j $(nproc) + testlib-quick-gem5-builds: + runs-on: [self-hosted, linux, x64, build] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id, testlib-quick-matrix] + strategy: + matrix: + build-target: ${{ fromJson(needs.testlib-quick-matrix.outputs.build-matrix) }} + steps: + - uses: actions/checkout@v3 + - name: Build gem5 + run: scons ${{ matrix.build-target }} -j $(nproc) # Upload the gem5 binary as an artifact. # Note: the "achor.txt" file is a hack to make sure the paths are @@ -109,72 +110,70 @@ jobs: # Then upload-artifact will upload "ARM/gem5.opt" and "RISCV/gem5.opt", # stripping the "build" directory. By adding the "anchor.txt" file, we # ensure the "build" directory is preserved. - - run: echo "anchor" > anchor.txt - - uses: actions/upload-artifact@v3 - with: - name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds - path: | - build/*/gem5.* - anchor.txt - retention-days: 7 + - run: echo "anchor" > anchor.txt + - uses: actions/upload-artifact@v3 + with: + name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds + path: | + build/*/gem5.* + anchor.txt + retention-days: 7 - testlib-quick-execution: - runs-on: [self-hosted, linux, x64, run] - if: github.event.pull_request.draft == false - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds] - timeout-minutes: 360 # 6 hours - strategy: - fail-fast: false - matrix: - test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }} - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true + testlib-quick-execution: + runs-on: [self-hosted, linux, x64, run] + if: github.event.pull_request.draft == false + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + needs: [pre-commit, check-for-change-id, testlib-quick-matrix, testlib-quick-gem5-builds] + timeout-minutes: 360 # 6 hours + strategy: + fail-fast: false + matrix: + test-dir: ${{ fromJson(needs.testlib-quick-matrix.outputs.test-dirs-matrix) }} + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true # Checkout the repository then download the gem5.opt artifact. - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 - with: - name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds + - uses: actions/checkout@v3 + - uses: actions/download-artifact@v3 + with: + name: ci-tests-${{ github.run_number }}-testlib-quick-all-gem5-builds # Check that the gem5.opt artifact exists and is executable. - - name: Chmod gem5.{opt,debug,fast} to be executable - run: | - find . -name "gem5.opt" -exec chmod u+x {} \; - find . -name "gem5.debug" -exec chmod u+x {} \; - find . -name "gem5.fast" -exec chmod u+x {} \; + - name: Chmod gem5.{opt,debug,fast} to be executable + run: | + find . -name "gem5.opt" -exec chmod u+x {} \; + find . -name "gem5.debug" -exec chmod u+x {} \; + find . -name "gem5.fast" -exec chmod u+x {} \; # Run the testlib quick tests in the given directory. - - name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests - id: run-tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run --skip-build -vv ${{ matrix.test-dir }} + - name: Run "tests/${{ matrix.test-dir }}" TestLib quick tests + id: run-tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run --skip-build -vv ${{ matrix.test-dir }} # Get the basename of the matrix.test-dir path (to name the artifact). - - name: Sanatize test-dir for artifact name - id: sanitize-test-dir - if: success() || failure() - run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT + - name: Sanatize test-dir for artifact name + id: sanitize-test-dir + if: success() || failure() + run: echo "sanatized-test-dir=$(echo '${{ matrix.test-dir }}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT # Upload the tests/testing-results directory as an artifact. - - name: Upload test results - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: ci-tests-run-${{ github.run_number }}-attempt-${{ github.run_attempt }}-testlib-quick-${{ steps.sanitize-test-dir.outputs.sanatized-test-dir }}-status-${{ steps.run-tests.outcome }}-output - path: tests/testing-results - retention-days: 30 + - name: Upload test results + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: ci-tests-run-${{ github.run_number }}-attempt-${{ github.run_attempt }}-testlib-quick-${{ steps.sanitize-test-dir.outputs.sanatized-test-dir + }}-status-${{ steps.run-tests.outcome }}-output + path: tests/testing-results + retention-days: 30 - testlib-quick: + testlib-quick: # It is 'testlib-quick' which needs to pass for the pull request to be # merged. The 'testlib-quick-execution' is a matrix job which runs all the # the testlib quick tests. This job is therefore a stub which will pass if # all the testlib-quick-execution jobs pass. - runs-on: [self-hosted, linux, x64, run] - needs: testlib-quick-execution - steps: - - run: echo "This job's status is ${{ job.status }}." + runs-on: [self-hosted, linux, x64, run] + needs: testlib-quick-execution + steps: + - run: echo "This job's status is ${{ job.status }}." diff --git a/.github/workflows/compiler-tests.yaml b/.github/workflows/compiler-tests.yaml index 595e231323..00c9482e3b 100644 --- a/.github/workflows/compiler-tests.yaml +++ b/.github/workflows/compiler-tests.yaml @@ -1,52 +1,57 @@ +--- # This workflow runs all of the compiler tests name: Compiler Tests on: # Runs every Friday from 7AM UTC - schedule: - - cron: '00 7 * * 5' + schedule: + - cron: 00 7 * * 5 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: # replication of compiler-tests.sh - all-compilers: - strategy: - fail-fast: false - matrix: - image: [gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-9, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, clang-version-13, clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies] - opts: [.opt, .fast] - runs-on: [self-hosted, linux, x64, build] - timeout-minutes: 2880 # 48 hours - container: gcr.io/gem5-test/${{ matrix.image }}:latest - steps: - - uses: actions/checkout@v3 - with: + all-compilers: + strategy: + fail-fast: false + matrix: + image: [gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-9, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, + clang-version-13, clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, + ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies] + opts: [.opt, .fast] + runs-on: [self-hosted, linux, x64, build] + timeout-minutes: 2880 # 48 hours + container: gcr.io/gem5-test/${{ matrix.image }}:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/ALL/gem5${{ matrix.opts }} with ${{ matrix.image }} - run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/ALL/gem5${{ matrix.opts }} -j$(nproc) - timeout-minutes: 600 # 10 hours + ref: develop + - name: Compile build/ALL/gem5${{ matrix.opts }} with ${{ matrix.image }} + run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/ALL/gem5${{ matrix.opts }} -j$(nproc) + timeout-minutes: 600 # 10 hours # Tests the two latest gcc and clang supported compilers against all gem5 compilations. - latest-compilers-all-gem5-builds: - strategy: - fail-fast: false - matrix: - gem5-compilation: [ARM, ARM_MESI_Three_Level, ARM_MESI_Three_Level_HTM, ARM_MOESI_hammer, Garnet_standalone, GCN3_X86, MIPS, 'NULL', NULL_MESI_Two_Level, NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86, GCN3_X86] - image: [gcc-version-12, clang-version-16] - opts: [.opt] - runs-on: [self-hosted, linux, x64, build] - timeout-minutes: 2880 # 48 hours - container: gcr.io/gem5-test/${{ matrix.image }}:latest - steps: - - uses: actions/checkout@v3 - with: + latest-compilers-all-gem5-builds: + strategy: + fail-fast: false + matrix: + gem5-compilation: [ARM, ARM_MESI_Three_Level, ARM_MESI_Three_Level_HTM, ARM_MOESI_hammer, Garnet_standalone, GCN3_X86, MIPS, 'NULL', NULL_MESI_Two_Level, + NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86, + GCN3_X86] + image: [gcc-version-12, clang-version-16] + opts: [.opt] + runs-on: [self-hosted, linux, x64, build] + timeout-minutes: 2880 # 48 hours + container: gcr.io/gem5-test/${{ matrix.image }}:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} with ${{ matrix.image }} - run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} -j$(nproc) - timeout-minutes: 600 # 10 hours + ref: develop + - name: Compile build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} with ${{ matrix.image }} + run: /usr/bin/env python3 /usr/bin/scons --ignore-style build/${{ matrix.gem5-compilation }}/gem5${{ matrix.opts }} -j$(nproc) + timeout-minutes: 600 # 10 hours diff --git a/.github/workflows/daily-tests.yaml b/.github/workflows/daily-tests.yaml index 06d37c86a8..13fca4cd92 100644 --- a/.github/workflows/daily-tests.yaml +++ b/.github/workflows/daily-tests.yaml @@ -1,286 +1,286 @@ +--- # This workflow runs all of the long tests within main.py, extra tests in nightly.sh, and unittests name: Daily Tests on: # Runs every day from 7AM UTC - schedule: - - cron: '0 7 * * *' + schedule: + - cron: 0 7 * * * jobs: - name-artifacts: - runs-on: ubuntu-latest - outputs: - build-name: ${{ steps.artifact-name.outputs.name }} - steps: - - uses: actions/checkout@v2 - - id: artifact-name - run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT + name-artifacts: + runs-on: ubuntu-latest + outputs: + build-name: ${{ steps.artifact-name.outputs.name }} + steps: + - uses: actions/checkout@v2 + - id: artifact-name + run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S-")" >> $GITHUB_OUTPUT - build-gem5: - strategy: - fail-fast: false - matrix: + build-gem5: + strategy: + fail-fast: false + matrix: # NULL is in quotes since it is considered a keyword in yaml files - image: [ALL, ALL_CHI, ARM, ALL_MSI, ALL_MESI_Two_Level, "NULL", NULL_MI_example, RISCV, VEGA_X86] + image: [ALL, ALL_CHI, ARM, ALL_MSI, ALL_MESI_Two_Level, 'NULL', NULL_MI_example, RISCV, VEGA_X86] # this allows us to pass additional command line parameters # the default is to add -j $(nproc), but some images # require more specifications when built - include: - - command-line: -j $(nproc) - - image: ALL_CHI - command-line: --default=ALL PROTOCOL=CHI -j $(nproc) - - image: ALL_MSI - command-line: --default=ALL PROTOCOL=MSI -j $(nproc) - - image: ALL_MESI_Two_Level - command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc) - - image: NULL_MI_example - command-line: --default=NULL PROTOCOL=MI_example -j $(nproc) - runs-on: [self-hosted, linux, x64, build] - needs: name-artifacts - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - steps: - - uses: actions/checkout@v3 - with: + include: + - command-line: -j $(nproc) + - image: ALL_CHI + command-line: --default=ALL PROTOCOL=CHI -j $(nproc) + - image: ALL_MSI + command-line: --default=ALL PROTOCOL=MSI -j $(nproc) + - image: ALL_MESI_Two_Level + command-line: --default=ALL PROTOCOL=MESI_Two_Level -j $(nproc) + - image: NULL_MI_example + command-line: --default=NULL PROTOCOL=MI_example -j $(nproc) + runs-on: [self-hosted, linux, x64, build] + needs: name-artifacts + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build gem5 - run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }} - - uses: actions/upload-artifact@v3 - with: - name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }} - path: build/${{ matrix.image }}/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - name: Build gem5 + run: scons build/${{ matrix.image }}/gem5.opt ${{ matrix.command-line }} + - uses: actions/upload-artifact@v3 + with: + name: ${{ needs.name-artifacts.outputs.build-name }}${{ matrix.image }} + path: build/${{ matrix.image }}/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." # this builds both unittests.fast and unittests.debug - unittests-fast-debug: - strategy: - matrix: - type: [fast, debug] - runs-on: [self-hosted, linux, x64, run] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v3 - with: + unittests-fast-debug: + strategy: + matrix: + type: [fast, debug] + runs-on: [self-hosted, linux, x64, run] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: ALL/unittests.${{ matrix.type }} UnitTests - run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc) + ref: develop + - name: ALL/unittests.${{ matrix.type }} UnitTests + run: scons build/ALL/unittests.${{ matrix.type }} -j $(nproc) # start running all of the long tests - testlib-long-tests: - strategy: - fail-fast: false - matrix: - test-type: [arm_boot_tests, fs, gpu, insttest_se, learning_gem5, m5threads_test_atomic, memory, multi_isa, replacement_policies, riscv_boot_tests, stdlib, x86_boot_tests] - runs-on: [self-hosted, linux, x64, run] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [name-artifacts, build-gem5] - timeout-minutes: 1440 # 24 hours for entire matrix to run - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-long-tests: + strategy: + fail-fast: false + matrix: + test-type: [arm_boot_tests, fs, gpu, insttest_se, learning_gem5, m5threads_test_atomic, memory, multi_isa, replacement_policies, riscv_boot_tests, + stdlib, x86_boot_tests] + runs-on: [self-hosted, linux, x64, run] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [name-artifacts, build-gem5] + timeout-minutes: 1440 # 24 hours for entire matrix to run + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop + ref: develop # download all artifacts for each test # since long tests can't start until the build matrix completes, # we download all artifacts from the build for each test # in this matrix - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI - path: build/ALL_CHI - - run: chmod u+x build/ALL_CHI/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ARM - path: build/ARM - - run: chmod u+x build/ARM/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI - path: build/ALL_MSI - - run: chmod u+x build/ALL_MSI/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level - path: build/ALL_MESI_Two_Level - - run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}NULL - path: build/NULL - - run: chmod u+x build/NULL/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example - path: build/NULL_MI_example - - run: chmod u+x build/NULL_MI_example/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}RISCV - path: build/RISCV - - run: chmod u+x build/RISCV/gem5.opt - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86 - path: build/VEGA_X86 - - run: chmod u+x build/VEGA_X86/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_CHI + path: build/ALL_CHI + - run: chmod u+x build/ALL_CHI/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ARM + path: build/ARM + - run: chmod u+x build/ARM/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_MSI + path: build/ALL_MSI + - run: chmod u+x build/ALL_MSI/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL_MESI_Two_Level + path: build/ALL_MESI_Two_Level + - run: chmod u+x build/ALL_MESI_Two_Level/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}NULL + path: build/NULL + - run: chmod u+x build/NULL/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}NULL_MI_example + path: build/NULL_MI_example + - run: chmod u+x build/NULL_MI_example/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}RISCV + path: build/RISCV + - run: chmod u+x build/RISCV/gem5.opt + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}VEGA_X86 + path: build/VEGA_X86 + - run: chmod u+x build/VEGA_X86/gem5.opt # run test - - name: long ${{ matrix.test-type }} tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc) - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + - name: long ${{ matrix.test-type }} tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run gem5/${{ matrix.test-type }} --length=long --skip-build -vv -t $(nproc) + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." # split library example tests into runs based on Suite UID # so that they don't hog the runners for too long - testlib-long-gem5_library_example_tests: - runs-on: [self-hosted, linux, x64, run] - strategy: - fail-fast: false - matrix: - test-type: [gem5-library-example-x86-ubuntu-run-ALL-x86_64-opt, gem5-library-example-riscv-ubuntu-run-ALL-x86_64-opt, lupv-example-ALL-x86_64-opt, gem5-library-example-arm-ubuntu-run-test-ALL-x86_64-opt, gem5-library-example-riscvmatched-hello-ALL-x86_64-opt] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [name-artifacts, build-gem5] - timeout-minutes: 1440 # 24 hours - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-long-gem5_library_example_tests: + runs-on: [self-hosted, linux, x64, run] + strategy: + fail-fast: false + matrix: + test-type: [gem5-library-example-x86-ubuntu-run-ALL-x86_64-opt, gem5-library-example-riscv-ubuntu-run-ALL-x86_64-opt, lupv-example-ALL-x86_64-opt, + gem5-library-example-arm-ubuntu-run-test-ALL-x86_64-opt, gem5-library-example-riscvmatched-hello-ALL-x86_64-opt] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [name-artifacts, build-gem5] + timeout-minutes: 1440 # 24 hours + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: ${{needs.name-artifacts.outputs.build-name}}ALL - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - name: long ${{ matrix.test-type }} gem5_library_example_tests - working-directory: ${{ github.workspace }}/tests - run: ./main.py run --uid SuiteUID:tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py:test-${{ matrix.test-type }} --length=long --skip-build -vv - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - uses: actions/download-artifact@v3 + with: + name: ${{needs.name-artifacts.outputs.build-name}}ALL + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - name: long ${{ matrix.test-type }} gem5_library_example_tests + working-directory: ${{ github.workspace }}/tests + run: ./main.py run --uid SuiteUID:tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py:test-${{ matrix.test-type }} --length=long + --skip-build -vv + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." # This runs the SST-gem5 integration compilation and tests it with # ext/sst/sst/example.py. - sst-test: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/sst-env:latest - timeout-minutes: 180 + sst-test: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/sst-env:latest + timeout-minutes: 180 - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build RISCV/libgem5_opt.so with SST - run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc) - - name: Compile ext/sst - working-directory: ${{ github.workspace }}/ext/sst - run: make -j $(nproc) - - name: Run SST test - working-directory: ${{ github.workspace }}/ext/sst - run: sst --add-lib-path=./ sst/example.py + ref: develop + - name: Build RISCV/libgem5_opt.so with SST + run: scons build/RISCV/libgem5_opt.so --without-tcmalloc --duplicate-sources --ignore-style -j $(nproc) + - name: Compile ext/sst + working-directory: ${{ github.workspace }}/ext/sst + run: make -j $(nproc) + - name: Run SST test + working-directory: ${{ github.workspace }}/ext/sst + run: sst --add-lib-path=./ sst/example.py # This runs the gem5 within SystemC ingration and runs a simple hello-world # simulation with it. - systemc-test: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/systemc-env:latest - timeout-minutes: 180 + systemc-test: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/systemc-env:latest + timeout-minutes: 180 - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build ARM/gem5.opt - run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc) - - name: Build ARM/libgem5_opt.so - run: scons build/ARM/libgem5_opt.so --with-cxx-config --without-python --without-tcmalloc USE_SYSTEMC=0 -j$(nproc) --duplicate-sources - - name: Compile gem5 withing SystemC - working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc - run: make - - name: Run gem5 within SystemC test - run: ./build/ARM/gem5.opt configs/deprecated/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello - - name: Continue gem5 within SystemC test - run: LD_LIBRARY_PATH=build/ARM/:/opt/systemc/lib-linux64/ ./util/systemc/gem5_within_systemc/gem5.opt.sc m5out/config.ini + ref: develop + - name: Build ARM/gem5.opt + run: scons build/ARM/gem5.opt --ignore-style --duplicate-sources -j$(nproc) + - name: Build ARM/libgem5_opt.so + run: scons build/ARM/libgem5_opt.so --with-cxx-config --without-python --without-tcmalloc USE_SYSTEMC=0 -j$(nproc) --duplicate-sources + - name: Compile gem5 withing SystemC + working-directory: ${{ github.workspace }}/util/systemc/gem5_within_systemc + run: make + - name: Run gem5 within SystemC test + run: ./build/ARM/gem5.opt configs/deprecated/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello + - name: Continue gem5 within SystemC test + run: LD_LIBRARY_PATH=build/ARM/:/opt/systemc/lib-linux64/ ./util/systemc/gem5_within_systemc/gem5.opt.sc m5out/config.ini # Runs the gem5 Nighyly GPU tests. - gpu-tests: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/gcn-gpu:latest - timeout-minutes: 720 # 12 hours + gpu-tests: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/gcn-gpu:latest + timeout-minutes: 720 # 12 hours - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Compile build/GCN3_X86/gem5.opt - run: scons build/GCN3_X86/gem5.opt -j $(nproc) - - name: Get Square test-prog from gem5-resources - uses: wei/wget@v1 - with: - args: -q http://dist.gem5.org/dist/develop/test-progs/square/square # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time: https://github.com/coder/sshcode/issues/102 - - name: Run Square test with GCN3_X86/gem5.opt (SE mode) - run: | - mkdir -p tests/testing-results - ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square - - name: Get allSyncPrims-1kernel from gem5-resources - uses: wei/wget@v1 - with: - args: -q http://dist.gem5.org/dist/develop/test-progs/heterosync/gcn3/allSyncPrims-1kernel # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time - - name: Run allSyncPrims-1kernel sleepMutex test with GCN3_X86/gem5.opt (SE mode) - run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="sleepMutex 10 16 4" - - name: Run allSyncPrims-1kernel lfTreeBarrUsing test with GCN3_X86/gem5.opt (SE mode) - run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="lfTreeBarrUniq 10 16 4" + ref: develop + - name: Compile build/GCN3_X86/gem5.opt + run: scons build/GCN3_X86/gem5.opt -j $(nproc) + - name: Get Square test-prog from gem5-resources + uses: wei/wget@v1 + with: + args: -q http://dist.gem5.org/dist/develop/test-progs/square/square # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time: https://github.com/coder/sshcode/issues/102 + - name: Run Square test with GCN3_X86/gem5.opt (SE mode) + run: | + mkdir -p tests/testing-results + ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c square + - name: Get allSyncPrims-1kernel from gem5-resources + uses: wei/wget@v1 + with: + args: -q http://dist.gem5.org/dist/develop/test-progs/heterosync/gcn3/allSyncPrims-1kernel # Removed -N bc it wasn't available within actions, should be okay bc workspace is clean every time + - name: Run allSyncPrims-1kernel sleepMutex test with GCN3_X86/gem5.opt (SE mode) + run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="sleepMutex 10 16 + 4" + - name: Run allSyncPrims-1kernel lfTreeBarrUsing test with GCN3_X86/gem5.opt (SE mode) + run: ./build/GCN3_X86/gem5.opt configs/example/apu_se.py --reg-alloc-policy=dynamic -n3 -c allSyncPrims-1kernel --options="lfTreeBarrUniq + 10 16 4" diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 19cf02c582..1db41ca339 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -1,53 +1,54 @@ +--- name: Docker images build and push on: - workflow_dispatch: + workflow_dispatch: jobs: - obtain-dockerfiles: - runs-on: [self-hosted, linux, x64, run] - container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest + obtain-dockerfiles: + runs-on: [self-hosted, linux, x64, run] + container: ghcr.io/gem5/ubuntu-22.04_all-dependencies:latest - steps: - - uses: actions/checkout@v3 - with: + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/upload-artifact@v3 - with: - name: dockerfiles - path: util/dockerfiles + ref: develop + - uses: actions/upload-artifact@v3 + with: + name: dockerfiles + path: util/dockerfiles # This builds and pushes the docker image. - build-and-push: - runs-on: [self-hosted, linux, x64, run] - needs: obtain-dockerfiles - permissions: - packages: write - contents: read + build-and-push: + runs-on: [self-hosted, linux, x64, run] + needs: obtain-dockerfiles + permissions: + packages: write + contents: read - steps: - - uses: actions/download-artifact@v3 - with: - name: dockerfiles - path: dockerfiles-docker-build + steps: + - uses: actions/download-artifact@v3 + with: + name: dockerfiles + path: dockerfiles-docker-build - - uses: docker/setup-qemu-action@v2 - name: Setup QEMU + - uses: docker/setup-qemu-action@v2 + name: Setup QEMU - - uses: docker/setup-buildx-action@v2 - name: Set up Docker Buildx + - uses: docker/setup-buildx-action@v2 + name: Set up Docker Buildx - - uses: docker/login-action@v2 - name: Login to the GitHub Container Registry - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/login-action@v2 + name: Login to the GitHub Container Registry + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push with bake - uses: docker/bake-action@v4 - with: - workdir: ./dockerfiles-docker-build - files: docker-bake.hcl - push: true + - name: Build and push with bake + uses: docker/bake-action@v4 + with: + workdir: ./dockerfiles-docker-build + files: docker-bake.hcl + push: true diff --git a/.github/workflows/gpu-tests.yaml b/.github/workflows/gpu-tests.yaml index c6e0155ecf..298d655b7d 100644 --- a/.github/workflows/gpu-tests.yaml +++ b/.github/workflows/gpu-tests.yaml @@ -1,60 +1,61 @@ +--- # This workflow runs all of the very-long tests within main.py name: Weekly Tests on: # Runs every Sunday from 7AM UTC - schedule: - - cron: '00 7 * * 6' + schedule: + - cron: 00 7 * * 6 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: - build-gem5: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/gcn-gpu:latest - steps: - - uses: actions/checkout@v3 - with: + build-gem5: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/gcn-gpu:latest + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - name: Build gem5 - run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style - - uses: actions/upload-artifact@v3 - with: - name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 - path: build/GCN3_X86/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - name: Build gem5 + run: scons build/GCN3_X86/gem5.opt -j $(nproc) --ignore-style + - uses: actions/upload-artifact@v3 + with: + name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 + path: build/GCN3_X86/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." - HACC-tests: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/gcn-gpu:latest - needs: build-gem5 - timeout-minutes: 120 # 2 hours - steps: - - uses: actions/checkout@v3 - with: + HACC-tests: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/gcn-gpu:latest + needs: build-gem5 + timeout-minutes: 120 # 2 hours + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 - path: build/GCN3_X86 - - run: chmod u+x build/GCN3_X86/gem5.opt - - name: make hip directory - run: mkdir hip - - name: Compile m5ops and x86 - working-directory: ${{ github.workspace }}/util/m5 - run: | - export TERM=xterm-256color - scons build/x86/out/m5 - - name: Download tests - working-directory: ${{ github.workspace }}/hip - run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest - - name: Run HACC tests - working-directory: ${{ github.workspace }} - run: | - build/GCN3_X86/gem5.opt configs/example/apu_se.py -n3 --reg-alloc-policy=dynamic --benchmark-root=hip -c ForceTreeTest --options="0.5 0.1 64 0.1 1 N 12 rcb" + ref: develop + - uses: actions/download-artifact@v3 + with: + name: weekly-test-${{ github.run_number }}-attempt-${{ github.run_attempt }}-gem5-build-gcn3 + path: build/GCN3_X86 + - run: chmod u+x build/GCN3_X86/gem5.opt + - name: make hip directory + run: mkdir hip + - name: Compile m5ops and x86 + working-directory: ${{ github.workspace }}/util/m5 + run: | + export TERM=xterm-256color + scons build/x86/out/m5 + - name: Download tests + working-directory: ${{ github.workspace }}/hip + run: wget http://dist.gem5.org/dist/v22-1/test-progs/halo-finder/ForceTreeTest + - name: Run HACC tests + working-directory: ${{ github.workspace }} + run: | + build/GCN3_X86/gem5.opt configs/example/apu_se.py -n3 --reg-alloc-policy=dynamic --benchmark-root=hip -c ForceTreeTest --options="0.5 0.1 64 0.1 1 N 12 rcb" diff --git a/.github/workflows/utils.yaml b/.github/workflows/utils.yaml index 91d0bf1722..ccbd87c82f 100644 --- a/.github/workflows/utils.yaml +++ b/.github/workflows/utils.yaml @@ -1,19 +1,21 @@ +--- # This workflow file contains miscellaneous tasks to manage the repository. name: Utils for Repository on: - schedule: - - cron: '30 1 * * *' - workflow_dispatch: + schedule: + - cron: 30 1 * * * + workflow_dispatch: jobs: # This job runs the stale action to close issues that have been inactive for 30 days. # It is scheduled to run every day at 1:30 AM UTC. - close-stale-issues: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v8.0.0 - with: - close-issue-message: 'This issue is being closed because it has been inactive waiting for response for 30 days. If this is still an issue, please open a new issue and reference this one.' - days-before-stale: 21 - days-before-close: 7 - any-of-labels: 'needs details' + close-stale-issues: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v8.0.0 + with: + close-issue-message: This issue is being closed because it has been inactive waiting for response for 30 days. If this is still an issue, + please open a new issue and reference this one. + days-before-stale: 21 + days-before-close: 7 + any-of-labels: needs details diff --git a/.github/workflows/weekly-tests.yaml b/.github/workflows/weekly-tests.yaml index 782647cb81..6a6dcc6812 100644 --- a/.github/workflows/weekly-tests.yaml +++ b/.github/workflows/weekly-tests.yaml @@ -1,110 +1,108 @@ +--- # This workflow runs all of the very-long tests within main.py name: Weekly Tests on: # Runs every Sunday from 7AM UTC - schedule: - - cron: '00 7 * * 6' + schedule: + - cron: 00 7 * * 6 # Allows us to manually start workflow for testing - workflow_dispatch: + workflow_dispatch: jobs: - build-gem5: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - outputs: - build-name: ${{ steps.artifact-name.outputs.name }} - steps: - - uses: actions/checkout@v3 - with: + build-gem5: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + outputs: + build-name: ${{ steps.artifact-name.outputs.name }} + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - id: artifact-name - run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT - - name: Build gem5 - run: | - scons build/ALL/gem5.opt -j $(nproc) - - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.artifact-name.outputs.name }} - path: build/ALL/gem5.opt - retention-days: 5 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - id: artifact-name + run: echo "name=$(date +"%Y-%m-%d_%H.%M.%S")-ALL" >> $GITHUB_OUTPUT + - name: Build gem5 + run: | + scons build/ALL/gem5.opt -j $(nproc) + - uses: actions/upload-artifact@v3 + with: + name: ${{ steps.artifact-name.outputs.name }} + path: build/ALL/gem5.opt + retention-days: 5 + - run: echo "This job's status is ${{ job.status }}." # start running the very-long tests - testlib-very-long-tests: - strategy: - fail-fast: false - matrix: - test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests] - runs-on: [self-hosted, linux, x64, run] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - needs: [build-gem5] - timeout-minutes: 4320 # 3 days - steps: - - name: Clean runner - run: - rm -rf ./* || true - rm -rf ./.??* || true - rm -rf ~/.cache || true - - uses: actions/checkout@v3 - with: + testlib-very-long-tests: + strategy: + fail-fast: false + matrix: + test-type: [gem5_library_example_tests, gem5_resources, parsec_benchmarks, x86_boot_tests] + runs-on: [self-hosted, linux, x64, run] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + needs: [build-gem5] + timeout-minutes: 4320 # 3 days + steps: + - name: Clean runner + run: rm -rf ./* || true rm -rf ./.??* || true rm -rf ~/.cache || true + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop - - uses: actions/download-artifact@v3 - with: - name: ${{needs.build-gem5.outputs.build-name}} - path: build/ALL - - run: chmod u+x build/ALL/gem5.opt - - name: very-long ${{ matrix.test-type }} - working-directory: ${{ github.workspace }}/tests - run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc) - - name: create zip of results - if: success() || failure() - run: | - apt-get -y install zip - zip -r output.zip tests/testing-results - - name: upload zip - if: success() || failure() - uses: actions/upload-artifact@v3 - env: - MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} - with: - name: ${{ env.MY_STEP_VAR }} - path: output.zip - retention-days: 7 - - run: echo "This job's status is ${{ job.status }}." + ref: develop + - uses: actions/download-artifact@v3 + with: + name: ${{needs.build-gem5.outputs.build-name}} + path: build/ALL + - run: chmod u+x build/ALL/gem5.opt + - name: very-long ${{ matrix.test-type }} + working-directory: ${{ github.workspace }}/tests + run: ./main.py run gem5/${{ matrix.test-type }} --length very-long --skip-build -vv -t $(nproc) + - name: create zip of results + if: success() || failure() + run: | + apt-get -y install zip + zip -r output.zip tests/testing-results + - name: upload zip + if: success() || failure() + uses: actions/upload-artifact@v3 + env: + MY_STEP_VAR: ${{ matrix.test-type }}_COMMIT.${{github.sha}}_RUN.${{github.run_id}}_ATTEMPT.${{github.run_attempt}} + with: + name: ${{ env.MY_STEP_VAR }} + path: output.zip + retention-days: 7 + - run: echo "This job's status is ${{ job.status }}." - dramsys-tests: - runs-on: [self-hosted, linux, x64, build] - container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest - timeout-minutes: 4320 # 3 days - steps: - - uses: actions/checkout@v3 - with: + dramsys-tests: + runs-on: [self-hosted, linux, x64, build] + container: gcr.io/gem5-test/ubuntu-22.04_all-dependencies:latest + timeout-minutes: 4320 # 3 days + steps: + - uses: actions/checkout@v3 + with: # Scheduled workflows run on the default branch by default. We # therefore need to explicitly checkout the develop branch. - ref: develop + ref: develop - - name: Checkout DRAMSys - working-directory: ${{ github.workspace }}/ext/dramsys - run: | - git clone https://github.com/tukl-msd/DRAMSys DRAMSys - cd DRAMSys - git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f - git submodule update --init --recursive + - name: Checkout DRAMSys + working-directory: ${{ github.workspace }}/ext/dramsys + run: | + git clone https://github.com/tukl-msd/DRAMSys DRAMSys + cd DRAMSys + git checkout -b gem5 09f6dcbb91351e6ee7cadfc7bc8b29d97625db8f + git submodule update --init --recursive # gem5 is built separately because it depends on the DRAMSys library - - name: Build gem5 - working-directory: ${{ github.workspace }} - run: scons build/ALL/gem5.opt -j $(nproc) + - name: Build gem5 + working-directory: ${{ github.workspace }} + run: scons build/ALL/gem5.opt -j $(nproc) - - name: Run DRAMSys Checks - working-directory: ${{ github.workspace }} - run: | - ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/arm-hello-dramsys.py - ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/dramsys-traffic.py - ./build/ALL/gem5.opt configs/example/dramsys.py + - name: Run DRAMSys Checks + working-directory: ${{ github.workspace }} + run: | + ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/arm-hello-dramsys.py + ./build/ALL/gem5.opt configs/example/gem5_library/dramsys/dramsys-traffic.py + ./build/ALL/gem5.opt configs/example/dramsys.py diff --git a/MAINTAINERS.yaml b/MAINTAINERS.yaml index 02a8b3eb7b..6636f11e26 100644 --- a/MAINTAINERS.yaml +++ b/MAINTAINERS.yaml @@ -1,3 +1,4 @@ +--- # See CONTRIBUTING.md for details of gem5's contribution process. # # This file contains a list of gem5's subsystems and their @@ -40,246 +41,246 @@ # targeting that subsystem. arch: - desc: >- - General architecture-specific components - status: orphaned + desc: >- + General architecture-specific components + status: orphaned arch-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg arch-gcn3: - status: maintained - maintainers: - - Matt Sinclair - - Matt Porema + status: maintained + maintainers: + - Matt Sinclair + - Matt Porema arch-vega: - status: maintained - maintainers: - - Matt Sinclair - - Matt Porema + status: maintained + maintainers: + - Matt Sinclair + - Matt Porema arch-mips: - status: orphaned + status: orphaned arch-power: - status: orphaned + status: orphaned arch-riscv: - status: orphaned + status: orphaned arch-sparc: - status: orphaned + status: orphaned arch-x86: - status: orphaned + status: orphaned base: - status: orphaned + status: orphaned base-stats: - status: orphaned + status: orphaned configs: - status: orphaned - experts: - - Jason Lowe-Power + status: orphaned + experts: + - Jason Lowe-Power cpu: - desc: >- - General changes to all CPU models (e.g., BaseCPU) - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + General changes to all CPU models (e.g., BaseCPU) + status: orphaned + experts: + - Jason Lowe-Power cpu-kvm: - status: maintained - maintainers: - - Andreas Sandberg + status: maintained + maintainers: + - Andreas Sandberg cpu-minor: - status: orphaned + status: orphaned cpu-o3: - status: orphaned + status: orphaned cpu-simple: - status: orphaned - experts: - - Jason Lowe-Power + status: orphaned + experts: + - Jason Lowe-Power dev: - status: orphaned + status: orphaned dev-hsa: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba dev-amdgpu: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba dev-virtio: - status: maintained - maintainers: - - Andreas Sandberg + status: maintained + maintainers: + - Andreas Sandberg dev-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg doc: - status: orphaned + status: orphaned ext: - desc: >- - Components external to gem5 - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + Components external to gem5 + status: orphaned + experts: + - Jason Lowe-Power ext-testlib: - status: orphaned - experts: - - Bobby R. Bruce + status: orphaned + experts: + - Bobby R. Bruce fastmodel: - desc: >- - Changes relating to ARM Fast Models - status: orphaned + desc: >- + Changes relating to ARM Fast Models + status: orphaned gpu-compute: - status: maintained - maintainers: - - Matt Poremba + status: maintained + maintainers: + - Matt Poremba learning-gem5: - desc: >- - The code and configs for the Learning gem5 book - status: orphaned - experts: - - Jason Lowe-Power - - Bobby R. Bruce + desc: >- + The code and configs for the Learning gem5 book + status: orphaned + experts: + - Jason Lowe-Power + - Bobby R. Bruce stdlib: - desc: >- - The gem5 standard library found under `src/python/gem5` - status: maintained - maintainers: - - Bobby R. Bruce + desc: >- + The gem5 standard library found under `src/python/gem5` + status: maintained + maintainers: + - Bobby R. Bruce mem: - desc: >- - General memory system (e.g., XBar, Packet) - status: orphaned + desc: >- + General memory system (e.g., XBar, Packet) + status: orphaned mem-cache: - desc: >- - Classic caches and coherence - status: orphaned + desc: >- + Classic caches and coherence + status: orphaned mem-dram: - status: orphaned + status: orphaned mem-garnet: - desc: >- - Garnet subcomponent of Ruby - status: orphaned + desc: >- + Garnet subcomponent of Ruby + status: orphaned mem-ruby: - desc: >- - Ruby structures and protocols - status: maintained - maintainers: - - Matt Sinclair - experts: - - Jason Lowe-Power + desc: >- + Ruby structures and protocols + status: maintained + maintainers: + - Matt Sinclair + experts: + - Jason Lowe-Power misc: - desc: >- - Anything outside of the other categories - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + Anything outside of the other categories + status: orphaned + experts: + - Jason Lowe-Power python: - desc: >- - Python SimObject wrapping and infrastructure - status: orphaned - experts: - - Jason Lowe-Power - - Andreas Sandberg + desc: >- + Python SimObject wrapping and infrastructure + status: orphaned + experts: + - Jason Lowe-Power + - Andreas Sandberg resources: - desc: >- - The gem5-resources repo with auxiliary resources for simulation - status: maintained - maintainers: - - Bobby R. Bruce - experts: - - Jason Lowe-Power + desc: >- + The gem5-resources repo with auxiliary resources for simulation + status: maintained + maintainers: + - Bobby R. Bruce + experts: + - Jason Lowe-Power scons: - desc: >- - Build system - status: orphaned + desc: >- + Build system + status: orphaned sim: - desc: >- - General simulation components - status: orphaned - experts: - - Jason Lowe-Power + desc: >- + General simulation components + status: orphaned + experts: + - Jason Lowe-Power sim-se: - desc: >- - Syscall emulation - status: orphaned + desc: >- + Syscall emulation + status: orphaned system-arm: - status: maintained - maintainers: - - Giacomo Travaglini - - Andreas Sandberg + status: maintained + maintainers: + - Giacomo Travaglini + - Andreas Sandberg systemc: - desc: >- - Code for the gem5 SystemC implementation and interface - status: orphaned + desc: >- + Code for the gem5 SystemC implementation and interface + status: orphaned tests: - desc: >- - testing changes - status: maintained - maintainers: - - Bobby R. Bruce + desc: >- + testing changes + status: maintained + maintainers: + - Bobby R. Bruce util: - status: orphaned + status: orphaned util-docker: - status: maintained - maintainers: - - Bobby R. Bruce + status: maintained + maintainers: + - Bobby R. Bruce util-m5: - status: orphaned + status: orphaned util-gem5art: - status: orphaned + status: orphaned website: - desc: >- - The gem5-website repo which contains the gem5.org site - status: maintained - maintainers: - - Bobby R. Bruce - experts: - - Jason Lowe-Power + desc: >- + The gem5-website repo which contains the gem5.org site + status: maintained + maintainers: + - Bobby R. Bruce + experts: + - Jason Lowe-Power diff --git a/util/dockerfiles/docker-compose.yaml b/util/dockerfiles/docker-compose.yaml index fcbc3e9f70..a4f585f6d7 100644 --- a/util/dockerfiles/docker-compose.yaml +++ b/util/dockerfiles/docker-compose.yaml @@ -1,3 +1,4 @@ +--- version: '2' services: From 1fe0056d3b9b5a3d185e63b86afe7798165451a7 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 9 Oct 2023 14:00:21 -0700 Subject: [PATCH 20/20] configs,tests: Remove `mkdir` in simpoint-se-checkpoint.py This `mkdir` is problematic as it doesn't create the directory recursively. This casues errors if `dir` is `X/Y/Z` and both `Y` and `Z` has not been created. An error will be returned (`No such file or directory`). This issue was fixed with: https://github.com/gem5/gem5/pull/263. The checkpointing code already recursively creates directories as needed. Ergo was can remove this `mkdir` statement. Change-Id: Ibae38267c8ee1eba76d7834367aa1c54013365bc --- .../example/gem5_library/checkpoints/simpoints-se-checkpoint.py | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py b/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py index b5eb7e9912..5787bf4bfc 100644 --- a/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py +++ b/configs/example/gem5_library/checkpoints/simpoints-se-checkpoint.py @@ -128,7 +128,6 @@ board.set_se_simpoint_workload( ) dir = Path(args.checkpoint_path) -dir.mkdir(exist_ok=True) simulator = Simulator( board=board,