Jason Lowe-Power has uploaded this change for review. ( https://gem5-review.googlesource.com/2880

Change subject: cpu, configs: A different way to expose CPU names
......................................................................

cpu, configs: A different way to expose CPU names

Use Python magic to generate a list of CPUs instead of explicitly listing
them.

This is in contrast to
https://gem5-review.googlesource.com/c/2860
https://gem5-review.googlesource.com/c/2861
https://gem5-review.googlesource.com/c/2862

Currently just a draft proposal. Comments are welcome :)

When adding the following code to se.py you get the following result.

from common import O3_ARM_v7a_3
for cpu,cls in m5._cpu_models.iteritems():
    print cpu, cls
...
detailed DerivO3CPU
O3_ARM_v7a_3 O3_ARM_v7a_3
AtomicSimpleCPU AtomicSimpleCPU
trace TraceCPU
O3Checker O3Checker
kvm X86KvmCPU
DummyChecker DummyChecker
DerivO3CPU DerivO3CPU
atomic AtomicSimpleCPU
TimingSimpleCPU TimingSimpleCPU
timing TimingSimpleCPU
X86KvmCPU X86KvmCPU
TraceCPU TraceCPU
...

This also supports adding aliases to classes derived in pure python.

If this patch has support, I will provide a similar patch for the DRAM
models.

Change-Id: Iae64910ce3b54a9dc05c19ed196a5b282f6ada8a
Signed-off-by: Jason Lowe-Power <[email protected]>
---
M configs/common/CpuConfig.py
M src/cpu/BaseCPU.py
M src/cpu/kvm/BaseKvmCPU.py
M src/cpu/minor/MinorCPU.py
M src/cpu/o3/O3CPU.py
M src/cpu/simple/AtomicSimpleCPU.py
M src/cpu/simple/TimingSimpleCPU.py
M src/cpu/trace/TraceCPU.py
8 files changed, 55 insertions(+), 75 deletions(-)



diff --git a/configs/common/CpuConfig.py b/configs/common/CpuConfig.py
index 757ec2d..757fbe1 100644
--- a/configs/common/CpuConfig.py
+++ b/configs/common/CpuConfig.py
@@ -39,47 +39,13 @@
 import inspect
 import sys
 from textwrap import  TextWrapper
-
-# Dictionary of mapping names of real CPU models to classes.
-_cpu_classes = {}
-
-# CPU aliases. The CPUs listed here might not be compiled, we make
-# sure they exist before we add them to the CPU list. A target may be
-# specified as a tuple, in which case the first available CPU model in
-# the tuple will be used as the target.
-_cpu_aliases_all = [
-    ("timing", "TimingSimpleCPU"),
-    ("atomic", "AtomicSimpleCPU"),
-    ("minor", "MinorCPU"),
-    ("detailed", "DerivO3CPU"),
-    ("kvm", ("ArmKvmCPU", "ArmV8KvmCPU", "X86KvmCPU")),
-    ("trace", "TraceCPU"),
-    ]
-
-# Filtered list of aliases. Only aliases for existing CPUs exist in
-# this list.
-_cpu_aliases = {}
-
-
-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
+from O3_ARM_v7a import O3_ARM_v7a_3

 def get(name):
     """Get a CPU class from a user provided class name or alias."""

-    real_name = _cpu_aliases.get(name, name)
-
     try:
-        cpu_class = _cpu_classes[real_name]
+        cpu_class = m5._cpu_models[name]
         return cpu_class
     except KeyError:
         print "%s is not a valid CPU model." % (name,)
@@ -90,24 +56,21 @@

     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
-
-    if _cpu_aliases:
-        print "\nCPU aliases:"
-        for alias, target in _cpu_aliases.items():
-            print "\t%s => %s" % (alias, target)
+    for name, cls in sorted(m5._cpu_models.items()):
+        if name != cls.__name__:
+            print "\t%s => %s" % (name, cls.__name__)
+        else:
+            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 _cpu_classes.keys() + _cpu_aliases.keys()
+    return m5._cpu_models.keys()

 def config_etrace(cpu_cls, cpu_list, options):
     if issubclass(cpu_cls, m5.objects.DerivO3CPU):
@@ -132,27 +95,3 @@
     else:
fatal("%s does not support data dependency tracing. Use a CPU model of"
               " type or inherited from DerivO3CPU.", cpu_cls)
-
-# The ARM detailed CPU is special in the sense that it doesn't exist
-# in the normal object hierarchy, so we have to add it manually.
-try:
-    from O3_ARM_v7a import O3_ARM_v7a_3
-    _cpu_classes["arm_detailed"] = O3_ARM_v7a_3
-except:
-    pass
-
-# Add all CPUs in the object hierarchy.
-for name, cls in inspect.getmembers(m5.objects, is_cpu_class):
-    _cpu_classes[name] = cls
-
-for alias, target in _cpu_aliases_all:
-    if isinstance(target, tuple):
-        # Some aliases contain a list of CPU model sorted in priority
-        # order. Use the first target that's available.
-        for t in target:
-            if t in _cpu_classes:
-                _cpu_aliases[alias] = t
-                break
-    elif target in _cpu_classes:
-        # Normal alias
-        _cpu_aliases[alias] = target
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 7b8a615..a00503d 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -43,7 +43,10 @@

 import sys

+import m5
+
 from m5.defines import buildEnv
+from m5.SimObject import MetaSimObject
 from m5.params import *
 from m5.proxy import *

@@ -91,7 +94,39 @@
     from RiscvISA import RiscvISA
     isa_class = RiscvISA

+class MetaCPU(MetaSimObject):
+    """ Metaclass for all CPUs.
+
+ __init__ is executed for every subclass of BaseCPU. In this metaclass, + we collect all of the different CPUs that are derived from BaseCPU to
+        automatically populate command-line parameters.
+
+ This meta class adds one SimObject parameter, alias, which is an alias
+        for the CPU model and will appear on the command line.
+
+        NOTE: This must inherit from the same metaclass as BaseCPU's parent
+ class (i.e., MetaSimObject). If MemObject is updated with a new
+              metaclass, this must inherit from that metaclass.
+    """
+
+    # Create a new dictionary in the m5 module with all of the CPU types
+    m5._cpu_models = {}
+    MetaSimObject.init_keywords['alias'] = str
+
+    def __init__(cls, name, bases, attrs):
+        super(MetaCPU, cls).__init__(name, bases, attrs)
+        if cls.abstract:
+            # Abstract classes shouldn't appear in the list
+            return
+        m5._cpu_models[name] = cls
+        if hasattr(cls, 'alias') and not cls.alias in m5._cpu_models:
+ # NOTE: Base class will always call __init__ first. The alias is
+            # *not* inherited to the deriving class
+            m5._cpu_models[cls.alias] = cls
+
+
 class BaseCPU(MemObject):
+    __metaclass__ = MetaCPU
     type = 'BaseCPU'
     abstract = True
     cxx_header = "cpu/base.hh"
diff --git a/src/cpu/kvm/BaseKvmCPU.py b/src/cpu/kvm/BaseKvmCPU.py
index cc0b28f..e9c41a8 100644
--- a/src/cpu/kvm/BaseKvmCPU.py
+++ b/src/cpu/kvm/BaseKvmCPU.py
@@ -45,6 +45,7 @@
     type = 'BaseKvmCPU'
     cxx_header = "cpu/kvm/base.hh"
     abstract = True
+    alias = 'kvm'

     @classmethod
     def export_methods(cls, code):
diff --git a/src/cpu/minor/MinorCPU.py b/src/cpu/minor/MinorCPU.py
index 5954f7b..d550e38 100644
--- a/src/cpu/minor/MinorCPU.py
+++ b/src/cpu/minor/MinorCPU.py
@@ -175,6 +175,7 @@
 class MinorCPU(BaseCPU):
     type = 'MinorCPU'
     cxx_header = "cpu/minor/cpu.hh"
+    alias = 'minor'

     @classmethod
     def memory_mode(cls):
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index cab2cf3..f4d126b 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -37,6 +37,7 @@
 class DerivO3CPU(BaseCPU):
     type = 'DerivO3CPU'
     cxx_header = 'cpu/o3/deriv.hh'
+    alias = 'detailed'

     @classmethod
     def memory_mode(cls):
diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py
index 04592c6..2eb921e 100644
--- a/src/cpu/simple/AtomicSimpleCPU.py
+++ b/src/cpu/simple/AtomicSimpleCPU.py
@@ -49,6 +49,7 @@

     type = 'AtomicSimpleCPU'
     cxx_header = "cpu/simple/atomic.hh"
+    alias = 'atomic'

     @classmethod
     def memory_mode(cls):
diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py
index 25149ea..88edcfe 100644
--- a/src/cpu/simple/TimingSimpleCPU.py
+++ b/src/cpu/simple/TimingSimpleCPU.py
@@ -32,6 +32,7 @@
 class TimingSimpleCPU(BaseSimpleCPU):
     type = 'TimingSimpleCPU'
     cxx_header = "cpu/simple/timing.hh"
+    alias = 'timing'

     @classmethod
     def memory_mode(cls):
diff --git a/src/cpu/trace/TraceCPU.py b/src/cpu/trace/TraceCPU.py
index e108b1a..76487a7 100644
--- a/src/cpu/trace/TraceCPU.py
+++ b/src/cpu/trace/TraceCPU.py
@@ -46,6 +46,7 @@
     """
     type = 'TraceCPU'
     cxx_header = "cpu/trace/trace_cpu.hh"
+    alias = 'trace'

     @classmethod
     def memory_mode(cls):

--
To view, visit https://gem5-review.googlesource.com/2880
To unsubscribe, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iae64910ce3b54a9dc05c19ed196a5b282f6ada8a
Gerrit-Change-Number: 2880
Gerrit-PatchSet: 1
Gerrit-Owner: Jason Lowe-Power <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to