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:
Daniel R. Carvalho
2019-09-03 12:22:59 +02:00
committed by Daniel Carvalho
parent 3fee716f56
commit c957d00dfe
8 changed files with 78 additions and 104 deletions

View File

@@ -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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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):

View File

@@ -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):

View File

@@ -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)

View File

@@ -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',

View File

@@ -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")