configs: Port CPUConfig to use the common object list
Factor out ObjectList functionality from CPUConfig. Change-Id: I34ca55142e14559e584d38b6cca3aa5c20923521 Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20589 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
committed by
Daniel Carvalho
parent
3fee716f56
commit
c957d00dfe
@@ -40,66 +40,6 @@ from __future__ import absolute_import
|
||||
|
||||
from m5 import fatal
|
||||
import m5.objects
|
||||
import inspect
|
||||
import sys
|
||||
from textwrap import TextWrapper
|
||||
|
||||
# Dictionary of mapping names of real CPU models to classes.
|
||||
_cpu_classes = {}
|
||||
|
||||
|
||||
def is_cpu_class(cls):
|
||||
"""Determine if a class is a CPU that can be instantiated"""
|
||||
|
||||
# We can't use the normal inspect.isclass because the ParamFactory
|
||||
# and ProxyFactory classes have a tendency to confuse it.
|
||||
try:
|
||||
return issubclass(cls, m5.objects.BaseCPU) and \
|
||||
not cls.abstract and \
|
||||
not issubclass(cls, m5.objects.CheckerCPU)
|
||||
except (TypeError, AttributeError):
|
||||
return False
|
||||
|
||||
def _cpu_subclass_tester(name):
|
||||
cpu_class = getattr(m5.objects, name, None)
|
||||
|
||||
def tester(cls):
|
||||
return cpu_class is not None and cls is not None and \
|
||||
issubclass(cls, cpu_class)
|
||||
|
||||
return tester
|
||||
|
||||
is_kvm_cpu = _cpu_subclass_tester("BaseKvmCPU")
|
||||
is_noncaching_cpu = _cpu_subclass_tester("NonCachingSimpleCPU")
|
||||
|
||||
def get(name):
|
||||
"""Get a CPU class from a user provided class name or alias."""
|
||||
|
||||
try:
|
||||
cpu_class = _cpu_classes[name]
|
||||
return cpu_class
|
||||
except KeyError:
|
||||
print("%s is not a valid CPU model." % (name,))
|
||||
sys.exit(1)
|
||||
|
||||
def print_cpu_list():
|
||||
"""Print a list of available CPU classes including their aliases."""
|
||||
|
||||
print("Available CPU classes:")
|
||||
doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t")
|
||||
for name, cls in _cpu_classes.items():
|
||||
print("\t%s" % name)
|
||||
|
||||
# Try to extract the class documentation from the class help
|
||||
# string.
|
||||
doc = inspect.getdoc(cls)
|
||||
if doc:
|
||||
for line in doc_wrapper.wrap(doc):
|
||||
print(line)
|
||||
|
||||
def cpu_names():
|
||||
"""Return a list of valid CPU names."""
|
||||
return list(_cpu_classes.keys())
|
||||
|
||||
def config_etrace(cpu_cls, cpu_list, options):
|
||||
if issubclass(cpu_cls, m5.objects.DerivO3CPU):
|
||||
@@ -124,22 +64,3 @@ def config_etrace(cpu_cls, cpu_list, options):
|
||||
else:
|
||||
fatal("%s does not support data dependency tracing. Use a CPU model of"
|
||||
" type or inherited from DerivO3CPU.", cpu_cls)
|
||||
|
||||
# Add all CPUs in the object hierarchy.
|
||||
for name, cls in inspect.getmembers(m5.objects, is_cpu_class):
|
||||
_cpu_classes[name] = cls
|
||||
|
||||
|
||||
from m5.defines import buildEnv
|
||||
from importlib import import_module
|
||||
for package in [ "generic", buildEnv['TARGET_ISA']]:
|
||||
try:
|
||||
package = import_module(".cores." + package,
|
||||
package=__name__.rpartition('.')[0])
|
||||
except ImportError:
|
||||
# No timing models for this ISA
|
||||
continue
|
||||
|
||||
for mod_name, module in inspect.getmembers(package, inspect.ismodule):
|
||||
for name, cls in inspect.getmembers(module, is_cpu_class):
|
||||
_cpu_classes[name] = cls
|
||||
|
||||
@@ -103,3 +103,48 @@ class ObjectList(object):
|
||||
# Dictionary that maps names of real models to classes
|
||||
self._sub_classes = {}
|
||||
self._add_objects()
|
||||
|
||||
class CPUList(ObjectList):
|
||||
def _is_obj_class(self, cls):
|
||||
"""Determine if a class is a CPU that can be instantiated"""
|
||||
|
||||
# We can't use the normal inspect.isclass because the ParamFactory
|
||||
# and ProxyFactory classes have a tendency to confuse it.
|
||||
try:
|
||||
return super(CPUList, self)._is_obj_class(cls) and \
|
||||
not issubclass(cls, m5.objects.CheckerCPU)
|
||||
except (TypeError, AttributeError):
|
||||
return False
|
||||
|
||||
def _add_objects(self):
|
||||
super(CPUList, self)._add_objects()
|
||||
|
||||
from m5.defines import buildEnv
|
||||
from importlib import import_module
|
||||
for package in [ "generic", buildEnv['TARGET_ISA']]:
|
||||
try:
|
||||
package = import_module(".cores." + package,
|
||||
package=__name__.rpartition('.')[0])
|
||||
except ImportError:
|
||||
# No timing models for this ISA
|
||||
continue
|
||||
|
||||
for mod_name, module in \
|
||||
inspect.getmembers(package, inspect.ismodule):
|
||||
for name, cls in inspect.getmembers(module,
|
||||
self._is_obj_class):
|
||||
self._sub_classes[name] = cls
|
||||
|
||||
cpu_list = CPUList(m5.objects.BaseCPU)
|
||||
|
||||
def _subclass_tester(name):
|
||||
sub_class = getattr(m5.objects, name, None)
|
||||
|
||||
def tester(cls):
|
||||
return sub_class is not None and cls is not None and \
|
||||
issubclass(cls, sub_class)
|
||||
|
||||
return tester
|
||||
|
||||
is_kvm_cpu = _subclass_tester("BaseKvmCPU")
|
||||
is_noncaching_cpu = _subclass_tester("NonCachingSimpleCPU")
|
||||
|
||||
@@ -46,14 +46,14 @@ from m5.defines import buildEnv
|
||||
from m5.objects import *
|
||||
|
||||
from .Benchmarks import *
|
||||
from . import CpuConfig
|
||||
from . import ObjectList
|
||||
from . import BPConfig
|
||||
from . import HWPConfig
|
||||
from . import MemConfig
|
||||
from . import PlatformConfig
|
||||
|
||||
def _listCpuTypes(option, opt, value, parser):
|
||||
CpuConfig.print_cpu_list()
|
||||
ObjectList.cpu_list.print()
|
||||
sys.exit(0)
|
||||
|
||||
def _listBPTypes(option, opt, value, parser):
|
||||
@@ -163,7 +163,7 @@ def addCommonOptions(parser):
|
||||
action="callback", callback=_listCpuTypes,
|
||||
help="List available CPU types")
|
||||
parser.add_option("--cpu-type", type="choice", default="AtomicSimpleCPU",
|
||||
choices=CpuConfig.cpu_names(),
|
||||
choices=ObjectList.cpu_list.get_names(),
|
||||
help = "type of cpu to run with")
|
||||
parser.add_option("--list-bp-types",
|
||||
action="callback", callback=_listBPTypes,
|
||||
@@ -317,7 +317,8 @@ def addCommonOptions(parser):
|
||||
parser.add_option("--work-cpus-checkpoint-count", action="store", type="int",
|
||||
help="checkpoint and exit when active cpu count is reached")
|
||||
parser.add_option("--restore-with-cpu", action="store", type="choice",
|
||||
default="AtomicSimpleCPU", choices=CpuConfig.cpu_names(),
|
||||
default="AtomicSimpleCPU",
|
||||
choices=ObjectList.cpu_list.get_names(),
|
||||
help = "cpu type for restoring from a checkpoint")
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ import sys
|
||||
from os import getcwd
|
||||
from os.path import join as joinpath
|
||||
|
||||
from . import CpuConfig
|
||||
from common import CpuConfig
|
||||
from . import ObjectList
|
||||
from . import BPConfig
|
||||
from . import MemConfig
|
||||
|
||||
@@ -59,7 +60,7 @@ addToPath('../common')
|
||||
|
||||
def getCPUClass(cpu_type):
|
||||
"""Returns the required cpu class and the mode of operation."""
|
||||
cls = CpuConfig.get(cpu_type)
|
||||
cls = ObjectList.cpu_list.get(cpu_type)
|
||||
return cls, cls.memory_mode()
|
||||
|
||||
def setCPUClass(options):
|
||||
|
||||
@@ -45,9 +45,9 @@ import m5
|
||||
from m5.objects import *
|
||||
m5.util.addToPath('../../')
|
||||
from common.Caches import *
|
||||
from common import CpuConfig
|
||||
from common import ObjectList
|
||||
|
||||
have_kvm = "ArmV8KvmCPU" in CpuConfig.cpu_names()
|
||||
have_kvm = "ArmV8KvmCPU" in ObjectList.cpu_list.get_names()
|
||||
|
||||
class L1I(L1_ICache):
|
||||
tag_latency = 1
|
||||
@@ -169,7 +169,8 @@ class CpuCluster(SubSystem):
|
||||
|
||||
class AtomicCluster(CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock, cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("AtomicSimpleCPU"), None, None, None, None ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("AtomicSimpleCPU"), None,
|
||||
None, None, None ]
|
||||
super(AtomicCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
def addL1(self):
|
||||
@@ -177,7 +178,8 @@ class AtomicCluster(CpuCluster):
|
||||
|
||||
class KvmCluster(CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock, cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("ArmV8KvmCPU"), None, None, None, None ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("ArmV8KvmCPU"), None, None,
|
||||
None, None ]
|
||||
super(KvmCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
def addL1(self):
|
||||
|
||||
@@ -53,7 +53,7 @@ from m5.objects import *
|
||||
m5.util.addToPath("../../")
|
||||
|
||||
from common import SysPaths
|
||||
from common import CpuConfig
|
||||
from common import ObjectList
|
||||
from common import PlatformConfig
|
||||
from common.cores.arm import ex5_big, ex5_LITTLE
|
||||
|
||||
@@ -85,32 +85,33 @@ def _using_pdes(root):
|
||||
class BigCluster(devices.CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock,
|
||||
cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("O3_ARM_v7a_3"), devices.L1I, devices.L1D,
|
||||
devices.WalkCache, devices.L2 ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("O3_ARM_v7a_3"),
|
||||
devices.L1I, devices.L1D, devices.WalkCache, devices.L2 ]
|
||||
super(BigCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
|
||||
class LittleCluster(devices.CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock,
|
||||
cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("MinorCPU"), devices.L1I, devices.L1D,
|
||||
devices.WalkCache, devices.L2 ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("MinorCPU"), devices.L1I,
|
||||
devices.L1D, devices.WalkCache, devices.L2 ]
|
||||
super(LittleCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
|
||||
class Ex5BigCluster(devices.CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock,
|
||||
cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("ex5_big"), ex5_big.L1I, ex5_big.L1D,
|
||||
ex5_big.WalkCache, ex5_big.L2 ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("ex5_big"), ex5_big.L1I,
|
||||
ex5_big.L1D, ex5_big.WalkCache, ex5_big.L2 ]
|
||||
super(Ex5BigCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
|
||||
class Ex5LittleCluster(devices.CpuCluster):
|
||||
def __init__(self, system, num_cpus, cpu_clock,
|
||||
cpu_voltage="1.0V"):
|
||||
cpu_config = [ CpuConfig.get("ex5_LITTLE"), ex5_LITTLE.L1I,
|
||||
ex5_LITTLE.L1D, ex5_LITTLE.WalkCache, ex5_LITTLE.L2 ]
|
||||
cpu_config = [ ObjectList.cpu_list.get("ex5_LITTLE"),
|
||||
ex5_LITTLE.L1I, ex5_LITTLE.L1D, ex5_LITTLE.WalkCache,
|
||||
ex5_LITTLE.L2 ]
|
||||
super(Ex5LittleCluster, self).__init__(system, num_cpus, cpu_clock,
|
||||
cpu_voltage, *cpu_config)
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ from common.SysPaths import *
|
||||
from common.Benchmarks import *
|
||||
from common import Simulation
|
||||
from common import CacheConfig
|
||||
from common import MemConfig
|
||||
from common import CpuConfig
|
||||
from common import MemConfig
|
||||
from common import ObjectList
|
||||
from common import BPConfig
|
||||
from common.Caches import *
|
||||
from common import Options
|
||||
@@ -144,7 +145,8 @@ def build_test_system(np):
|
||||
test_sys.cpu = [TestCPUClass(clk_domain=test_sys.cpu_clk_domain, cpu_id=i)
|
||||
for i in range(np)]
|
||||
|
||||
if CpuConfig.is_kvm_cpu(TestCPUClass) or CpuConfig.is_kvm_cpu(FutureClass):
|
||||
if ObjectList.is_kvm_cpu(TestCPUClass) or \
|
||||
ObjectList.is_kvm_cpu(FutureClass):
|
||||
test_sys.kvm_vm = KvmVM()
|
||||
|
||||
if options.ruby:
|
||||
@@ -193,7 +195,7 @@ def build_test_system(np):
|
||||
|
||||
# Sanity check
|
||||
if options.simpoint_profile:
|
||||
if not CpuConfig.is_noncaching_cpu(TestCPUClass):
|
||||
if not ObjectList.is_noncaching_cpu(TestCPUClass):
|
||||
fatal("SimPoint generation should be done with atomic cpu")
|
||||
if np > 1:
|
||||
fatal("SimPoint generation not supported with more than one CPUs")
|
||||
@@ -278,7 +280,7 @@ def build_drive_system(np):
|
||||
print("Error: a kernel must be provided to run in full system mode")
|
||||
sys.exit(1)
|
||||
|
||||
if CpuConfig.is_kvm_cpu(DriveCPUClass):
|
||||
if ObjectList.is_kvm_cpu(DriveCPUClass):
|
||||
drive_sys.kvm_vm = KvmVM()
|
||||
|
||||
drive_sys.iobridge = Bridge(delay='50ns',
|
||||
|
||||
@@ -62,6 +62,7 @@ from common import Options
|
||||
from common import Simulation
|
||||
from common import CacheConfig
|
||||
from common import CpuConfig
|
||||
from common import ObjectList
|
||||
from common import BPConfig
|
||||
from common import MemConfig
|
||||
from common.FileSystemConfig import config_filesystem
|
||||
@@ -206,7 +207,7 @@ if options.elastic_trace_en:
|
||||
for cpu in system.cpu:
|
||||
cpu.clk_domain = system.cpu_clk_domain
|
||||
|
||||
if CpuConfig.is_kvm_cpu(CPUClass) or CpuConfig.is_kvm_cpu(FutureClass):
|
||||
if ObjectList.is_kvm_cpu(CPUClass) or ObjectList.is_kvm_cpu(FutureClass):
|
||||
if buildEnv['TARGET_ISA'] == 'x86':
|
||||
system.kvm_vm = KvmVM()
|
||||
for process in multiprocesses:
|
||||
@@ -217,7 +218,7 @@ if CpuConfig.is_kvm_cpu(CPUClass) or CpuConfig.is_kvm_cpu(FutureClass):
|
||||
|
||||
# Sanity check
|
||||
if options.simpoint_profile:
|
||||
if not CpuConfig.is_noncaching_cpu(CPUClass):
|
||||
if not ObjectList.is_noncaching_cpu(CPUClass):
|
||||
fatal("SimPoint/BPProbe should be done with an atomic cpu")
|
||||
if np > 1:
|
||||
fatal("SimPoint generation not supported with more than one CPUs")
|
||||
|
||||
Reference in New Issue
Block a user