diff options
44 files changed, 1293 insertions, 1452 deletions
diff --git a/SConstruct b/SConstruct index 9659b15ad..9c8a9dc54 100755 --- a/SConstruct +++ b/SConstruct @@ -1027,7 +1027,8 @@ if main['M5_BUILD_CACHE']: print 'Using build cache located at', main['M5_BUILD_CACHE'] CacheDir(main['M5_BUILD_CACHE']) -if not GetOption('without_python'): +main['USE_PYTHON'] = not GetOption('without_python') +if main['USE_PYTHON']: # Find Python include and library directories for embedding the # interpreter. We rely on python-config to resolve the appropriate # includes and linker flags. ParseConfig does not seem to understand diff --git a/src/SConscript b/src/SConscript index f1474c982..6cb497695 100755 --- a/src/SConscript +++ b/src/SConscript @@ -176,12 +176,11 @@ class Source(SourceFile): Source.current_group = group '''Add a c/c++ source file to the build''' - def __init__(self, source, Werror=True, swig=False, **guards): + def __init__(self, source, Werror=True, **guards): '''specify the source file, and any guards''' super(Source, self).__init__(source, **guards) self.Werror = Werror - self.swig = swig Source.source_groups[Source.current_group].append(self) @@ -243,24 +242,6 @@ class SimObject(PySource): bisect.insort_right(SimObject.modnames, self.modname) -class SwigSource(SourceFile): - '''Add a swig file to build''' - - def __init__(self, package, source, **guards): - '''Specify the python package, the source file, and any guards''' - super(SwigSource, self).__init__(source, skip_no_python=True, **guards) - - modname,ext = self.extname - assert ext == 'i' - - self.package = package - self.module = modname - cc_file = joinpath(self.dirname, modname + '_wrap.cc') - py_file = joinpath(self.dirname, modname + '.py') - - self.cc_source = Source(cc_file, swig=True, parent=self, **guards) - self.py_source = PySource(package, py_file, parent=self, **guards) - class ProtoBuf(SourceFile): '''Add a Protocol Buffer to build''' @@ -303,7 +284,6 @@ class UnitTest(object): Export('Source') Export('PySource') Export('SimObject') -Export('SwigSource') Export('ProtoBuf') Export('UnitTest') @@ -559,19 +539,6 @@ sys.meta_path.remove(importer) sim_objects = m5.SimObject.allClasses all_enums = m5.params.allEnums -if m5.SimObject.noCxxHeader: - print >> sys.stderr, \ - "warning: At least one SimObject lacks a header specification. " \ - "This can cause unexpected results in the generated SWIG " \ - "wrappers." - -# Find param types that need to be explicitly wrapped with swig. -# These will be recognized because the ParamDesc will have a -# swig_decl() method. Most param types are based on types that don't -# need this, either because they're based on native types (like Int) -# or because they're SimObjects (which get swigged independently). -# For now the only things handled here are VectorParam types. -params_to_swig = {} for name,obj in sorted(sim_objects.iteritems()): for param in obj._params.local.values(): # load the ptype attribute now because it depends on the @@ -580,12 +547,6 @@ for name,obj in sorted(sim_objects.iteritems()): # SimObject.allClasses will have been loaded param.ptype - if not hasattr(param, 'swig_decl'): - continue - pname = param.ptype_str - if pname not in params_to_swig: - params_to_swig[pname] = param - ######################################################################## # # calculate extra dependencies @@ -668,16 +629,6 @@ def createSimObjectCxxConfig(is_header): code.write(target[0].abspath) return body -def createParamSwigWrapper(target, source, env): - assert len(target) == 1 and len(source) == 1 - - name = str(source[0].get_contents()) - param = params_to_swig[name] - - code = code_formatter() - param.swig_decl(code) - code.write(target[0].abspath) - def createEnumStrings(target, source, env): assert len(target) == 1 and len(source) == 1 @@ -686,6 +637,8 @@ def createEnumStrings(target, source, env): code = code_formatter() obj.cxx_def(code) + if env['USE_PYTHON']: + obj.pybind_def(code) code.write(target[0].abspath) def createEnumDecls(target, source, env): @@ -698,28 +651,14 @@ def createEnumDecls(target, source, env): obj.cxx_decl(code) code.write(target[0].abspath) -def createEnumSwigWrapper(target, source, env): - assert len(target) == 1 and len(source) == 1 - - name = str(source[0].get_contents()) - obj = all_enums[name] - - code = code_formatter() - obj.swig_decl(code) - code.write(target[0].abspath) - -def createSimObjectSwigWrapper(target, source, env): +def createSimObjectPyBindWrapper(target, source, env): name = source[0].get_contents() obj = sim_objects[name] code = code_formatter() - obj.swig_decl(code) + obj.pybind_decl(code) code.write(target[0].abspath) -# dummy target for generated code -# we start out with all the Source files so they get copied to build/*/ also. -SWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) - # Generate all of the SimObject param C++ struct header files params_hh_files = [] for name,simobj in sorted(sim_objects.iteritems()): @@ -731,7 +670,6 @@ for name,simobj in sorted(sim_objects.iteritems()): env.Command(hh_file, Value(name), MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) env.Depends(hh_file, depends + extra_deps) - env.Depends(SWIG, hh_file) # C++ parameter description files if GetOption('with_cxx_config'): @@ -788,17 +726,6 @@ if GetOption('with_cxx_config'): [File('sim/cxx_config.hh')]) Source(cxx_config_init_cc_file) -# Generate any needed param SWIG wrapper files -params_i_files = [] -for name,param in sorted(params_to_swig.iteritems()): - i_file = File('python/_m5/%s.i' % (param.swig_module_name())) - params_i_files.append(i_file) - env.Command(i_file, Value(name), - MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) - env.Depends(i_file, depends) - env.Depends(SWIG, i_file) - SwigSource('_m5', i_file) - # Generate all enum header files for name,enum in sorted(all_enums.iteritems()): py_source = PySource.modules[enum.__module__] @@ -808,67 +735,24 @@ for name,enum in sorted(all_enums.iteritems()): env.Command(cc_file, Value(name), MakeAction(createEnumStrings, Transform("ENUM STR"))) env.Depends(cc_file, depends + extra_deps) - env.Depends(SWIG, cc_file) Source(cc_file) hh_file = File('enums/%s.hh' % name) env.Command(hh_file, Value(name), MakeAction(createEnumDecls, Transform("ENUMDECL"))) env.Depends(hh_file, depends + extra_deps) - env.Depends(SWIG, hh_file) - - i_file = File('python/_m5/enum_%s.i' % name) - env.Command(i_file, Value(name), - MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) - env.Depends(i_file, depends + extra_deps) - env.Depends(SWIG, i_file) - SwigSource('_m5', i_file) - -# Generate SimObject SWIG wrapper files -for name,simobj in sorted(sim_objects.iteritems()): - py_source = PySource.modules[simobj.__module__] - extra_deps = [ py_source.tnode ] - i_file = File('python/_m5/param_%s.i' % name) - env.Command(i_file, Value(name), - MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) - env.Depends(i_file, depends + extra_deps) - SwigSource('_m5', i_file) - -# Generate the main swig init file -def makeEmbeddedSwigInit(package): - def body(target, source, env): - assert len(target) == 1 and len(source) == 1 - code = code_formatter() - module = source[0].get_contents() - # Provide the full context so that the swig-generated call to - # Py_InitModule ends up placing the embedded module in the - # right package. - context = str(package) + "._" + str(module) - code('''\ - #include "sim/init.hh" - - extern "C" { - void init_${module}(); - } - - EmbeddedSwig embed_swig_${module}(init_${module}, "${context}"); - ''') - code.write(str(target[0])) - return body - -# Build all swig modules -for swig in SwigSource.all: - env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, - MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' - '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) - cc_file = str(swig.tnode) - init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) - env.Command(init_file, Value(swig.module), - MakeAction(makeEmbeddedSwigInit(swig.package), - Transform("EMBED SW"))) - env.Depends(SWIG, init_file) - Source(init_file, **swig.guards) +# Generate SimObject Python bindings wrapper files +if env['USE_PYTHON']: + for name,simobj in sorted(sim_objects.iteritems()): + py_source = PySource.modules[simobj.__module__] + extra_deps = [ py_source.tnode ] + cc_file = File('python/_m5/param_%s.cc' % name) + env.Command(cc_file, Value(name), + MakeAction(createSimObjectPyBindWrapper, + Transform("SO PyBind"))) + env.Depends(cc_file, depends + extra_deps) + Source(cc_file) # Build all protocol buffers if we have got protoc and protobuf available if env['HAVE_PROTOBUF']: @@ -882,7 +766,6 @@ if env['HAVE_PROTOBUF']: '--proto_path ${SOURCE.dir} $SOURCE', Transform("PROTOC"))) - env.Depends(SWIG, [proto.cc_file, proto.hh_file]) # Add the C++ source file Source(proto.cc_file, **proto.guards) elif ProtoBuf.all: @@ -982,11 +865,9 @@ for name,flag in sorted(debug_flags.iteritems()): hh_file = 'debug/%s.hh' % name env.Command(hh_file, Value(flag), MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) - env.Depends(SWIG, hh_file) env.Command('debug/flags.cc', Value(debug_flags), MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) -env.Depends(SWIG, 'debug/flags.cc') Source('debug/flags.cc') # version tags @@ -1052,7 +933,6 @@ EmbeddedPython embedded_${sym}( for source in PySource.all: env.Command(source.cpp, source.tnode, MakeAction(embedPyFile, Transform("EMBED PY"))) - env.Depends(SWIG, source.cpp) Source(source.cpp, skip_no_python=True) ######################################################################## @@ -1087,23 +967,7 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): new_env.Label = label new_env.Append(**kwargs) - swig_env = new_env.Clone() - - # Both gcc and clang have issues with unused labels and values in - # the SWIG generated code - swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) - if env['GCC']: - # Depending on the SWIG version, we also need to supress - # warnings about uninitialized variables and missing field - # initializers. - swig_env.Append(CCFLAGS=['-Wno-uninitialized', - '-Wno-missing-field-initializers', - '-Wno-unused-but-set-variable', - '-Wno-maybe-uninitialized', - '-Wno-type-limits']) - - # The address sanitizer is available for gcc >= 4.8 if GetOption('with_asan'): if GetOption('with_ubsan') and \ @@ -1125,10 +989,6 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): if env['CLANG']: - swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', - '-Wno-deprecated-register', - '-Wno-tautological-compare']) - # We require clang >= 3.1, so there is no need to check any # versions here. if GetOption('with_ubsan'): @@ -1158,9 +1018,7 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): build environment, and returns the corresponding SCons Object nodes''' - if source.swig: - env = swig_env - elif source.Werror: + if source.Werror: env = werror_env else: env = new_env @@ -1177,8 +1035,8 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): lib_guards = {'main': False, 'skip_lib': False} - # Without Python, leave out all SWIG and Python content from the - # library builds. The option doesn't affect gem5 built as a program + # Without Python, leave out all Python content from the library + # builds. The option doesn't affect gem5 built as a program if GetOption('without_python'): lib_guards['skip_no_python'] = False diff --git a/src/arch/arm/ArmPMU.py b/src/arch/arm/ArmPMU.py index 3baa39bc9..3802e49bc 100644 --- a/src/arch/arm/ArmPMU.py +++ b/src/arch/arm/ArmPMU.py @@ -38,7 +38,7 @@ # Andreas Sandberg from m5.defines import buildEnv -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * from m5.params import isNullPointer from m5.proxy import * @@ -48,12 +48,9 @@ class ArmPMU(SimObject): cxx_class = 'ArmISA::PMU' cxx_header = 'arch/arm/pmu.hh' - @classmethod - def export_methods(cls, code): - code(''' - void addEventProbe(unsigned int id, - SimObject *obj, const char *name); -''') + cxx_exports = [ + PyBindMethod("addEventProbe"), + ] # To prevent cycles in the configuration hierarchy, we don't keep # a list of supported events as a configuration param. Instead, we diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index 9100db09a..41f6b9d79 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -36,6 +36,7 @@ # Authors: Ali Saidi from m5.params import * +from m5.SimObject import * from System import System @@ -98,9 +99,10 @@ class LinuxArmSystem(GenericArmSystem): type = 'LinuxArmSystem' cxx_header = "arch/arm/linux/system.hh" - @classmethod - def export_methods(cls, code): - code('''void dumpDmesg();''') + @cxxMethod + def dumpDmesg(self): + """Dump dmesg from the simulated kernel to standard out""" + pass class FreebsdArmSystem(GenericArmSystem): type = 'FreebsdArmSystem' diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 7b8a615ea..550ba62ac 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -43,6 +43,7 @@ import sys +from m5.SimObject import * from m5.defines import buildEnv from m5.params import * from m5.proxy import * @@ -96,18 +97,16 @@ class BaseCPU(MemObject): abstract = True cxx_header = "cpu/base.hh" - @classmethod - def export_methods(cls, code): - code(''' - void switchOut(); - void takeOverFrom(BaseCPU *cpu); - bool switchedOut(); - void flushTLBs(); - Counter totalInsts(); - void scheduleInstStop(ThreadID tid, Counter insts, const char *cause); - void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause); - uint64_t getCurrentInstCount(ThreadID tid); -''') + cxx_exports = [ + PyBindMethod("switchOut"), + PyBindMethod("takeOverFrom"), + PyBindMethod("switchedOut"), + PyBindMethod("flushTLBs"), + PyBindMethod("totalInsts"), + PyBindMethod("scheduleInstStop"), + PyBindMethod("scheduleLoadStop"), + PyBindMethod("getCurrentInstCount"), + ] @classmethod def memory_mode(cls): diff --git a/src/cpu/kvm/BaseKvmCPU.py b/src/cpu/kvm/BaseKvmCPU.py index cc0b28fe9..cb9bf481a 100644 --- a/src/cpu/kvm/BaseKvmCPU.py +++ b/src/cpu/kvm/BaseKvmCPU.py @@ -35,6 +35,7 @@ # # Authors: Andreas Sandberg +from m5.SimObject import * from m5.params import * from m5.proxy import * @@ -46,11 +47,10 @@ class BaseKvmCPU(BaseCPU): cxx_header = "cpu/kvm/base.hh" abstract = True - @classmethod - def export_methods(cls, code): - code(''' - void dump() const; -''') + @cxxMethod + def dump(self): + """Dump the internal state of KVM to standard out.""" + pass @classmethod def memory_mode(cls): diff --git a/src/cpu/kvm/X86KvmCPU.py b/src/cpu/kvm/X86KvmCPU.py index 18a4d3d6f..411db7dbe 100644 --- a/src/cpu/kvm/X86KvmCPU.py +++ b/src/cpu/kvm/X86KvmCPU.py @@ -27,21 +27,20 @@ # Authors: Andreas Sandberg from m5.params import * +from m5.SimObject import * from BaseKvmCPU import BaseKvmCPU class X86KvmCPU(BaseKvmCPU): type = 'X86KvmCPU' cxx_header = "cpu/kvm/x86_cpu.hh" - @classmethod - def export_methods(cls, code): - code(''' - void dumpFpuRegs(); - void dumpIntRegs(); - void dumpSpecRegs(); - void dumpXCRs(); - void dumpXSave(); - void dumpVCpuEvents(); -''') + cxx_exports = [ + PyBindMethod("dumpFpuRegs"), + PyBindMethod("dumpIntRegs"), + PyBindMethod("dumpSpecRegs"), + PyBindMethod("dumpXCRs"), + PyBindMethod("dumpXSave"), + PyBindMethod("dumpVCpuEvents"), + ] useXSave = Param.Bool(True, "Use XSave to synchronize FPU/SIMD registers") diff --git a/src/python/SConscript b/src/python/SConscript index c1868f4b8..1e7746930 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -31,9 +31,6 @@ Import('*') -Source('swig/pyevent.cc', skip_no_python=True) -Source('swig/pyobject.cc', skip_no_python=True) - PySource('', 'importer.py') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') @@ -62,16 +59,13 @@ PySource('m5.util', 'm5/util/orderdict.py') PySource('m5.util', 'm5/util/smartdict.py') PySource('m5.util', 'm5/util/sorteddict.py') PySource('m5.util', 'm5/util/terminal.py') +PySource('m5.util', 'm5/util/pybind.py') -PySource('_m5', '_m5/__init__.py') -SwigSource('_m5', 'swig/core.i') -SwigSource('_m5', 'swig/debug.i') -SwigSource('_m5', 'swig/drain.i') -SwigSource('_m5', 'swig/event.i') -SwigSource('_m5', 'swig/pyobject.i') -SwigSource('_m5', 'swig/range.i') -SwigSource('_m5', 'swig/serialize.i') -SwigSource('_m5', 'swig/stats.i') -SwigSource('_m5', 'swig/trace.i') PySource('m5.internal', 'm5/internal/__init__.py') PySource('m5.internal', 'm5/internal/params.py') + +Source('pybind11/core.cc', skip_no_python=True) +Source('pybind11/debug.cc', skip_no_python=True) +Source('pybind11/event.cc', skip_no_python=True) +Source('pybind11/pyobject.cc', skip_no_python=True) +Source('pybind11/stats.cc', skip_no_python=True) diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 07df44240..5418c1f34 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -41,12 +41,16 @@ # Authors: Steve Reinhardt # Nathan Binkert # Andreas Hansson +# Andreas Sandberg import sys from types import FunctionType, MethodType, ModuleType +from functools import wraps +import inspect import m5 from m5.util import * +from m5.util.pybind import * # Have to import params up top since Param is referenced on initial # load (when SimObject class references Param to create a class @@ -268,7 +272,6 @@ def createCxxConfigDirectoryEntryFile(code, name, simobj, is_header): code('{') code.indent() code('this->name = name_;') - code('this->pyobj = NULL;') code.dedent() code('}') @@ -393,12 +396,16 @@ def createCxxConfigDirectoryEntryFile(code, name, simobj, is_header): # class are instantiated, and provides inherited instance behavior). class MetaSimObject(type): # Attributes that can be set only at initialization time - init_keywords = { 'abstract' : bool, - 'cxx_class' : str, - 'cxx_type' : str, - 'cxx_header' : str, - 'type' : str, - 'cxx_bases' : list } + init_keywords = { + 'abstract' : bool, + 'cxx_class' : str, + 'cxx_type' : str, + 'cxx_header' : str, + 'type' : str, + 'cxx_bases' : list, + 'cxx_exports' : list, + 'cxx_param_exports' : list, + } # Attributes that can be set any time keywords = { 'check' : FunctionType } @@ -415,7 +422,13 @@ class MetaSimObject(type): # filtered in __init__. cls_dict = {} value_dict = {} + cxx_exports = [] for key,val in dict.items(): + try: + cxx_exports.append(getattr(val, "__pybind")) + except AttributeError: + pass + if public_value(key, val): cls_dict[key] = val else: @@ -425,6 +438,12 @@ class MetaSimObject(type): value_dict['abstract'] = False if 'cxx_bases' not in value_dict: value_dict['cxx_bases'] = [] + if 'cxx_exports' not in value_dict: + value_dict['cxx_exports'] = cxx_exports + else: + value_dict['cxx_exports'] += cxx_exports + if 'cxx_param_exports' not in value_dict: + value_dict['cxx_param_exports'] = [] cls_dict['_value_dict'] = value_dict cls = super(MetaSimObject, mcls).__new__(mcls, name, bases, cls_dict) if 'type' in value_dict: @@ -654,6 +673,9 @@ class MetaSimObject(type): def cxx_predecls(cls, code): code('#include "params/$cls.hh"') + def pybind_predecls(cls, code): + code('#include "${{cls.cxx_header}}"') + # See ParamValue.swig_predecls for description. def swig_predecls(cls, code): code('%import "python/_m5/param_$cls.i"') @@ -755,6 +777,85 @@ using std::ptrdiff_t; code() code('%include "params/$cls.hh"') + def pybind_decl(cls, code): + class_path = cls.cxx_class.split('::') + namespaces, classname = class_path[:-1], class_path[-1] + py_class_name = '_COLONS_'.join(class_path) if namespaces else \ + classname; + + # The 'local' attribute restricts us to the params declared in + # the object itself, not including inherited params (which + # will also be inherited from the base class's param struct + # here). Sort the params based on their key + params = map(lambda (k, v): v, sorted(cls._params.local.items())) + ports = cls._ports.local + + code('''#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include "sim/sim_object.hh" +#include "params/$cls.hh" +#include "sim/init.hh" +#include "${{cls.cxx_header}}" + +''') + + for param in params: + param.pybind_predecls(code) + + code('''namespace py = pybind11; + +static void +module_init(py::module &m_internal) +{ + py::module m = m_internal.def_submodule("param_${cls}"); +''') + code.indent() + if cls._base: + code('py::class_<${cls}Params, ${{cls._base.type}}Params>(m, ' \ + '"${cls}Params")') + else: + code('py::class_<${cls}Params>(m, "${cls}Params")') + + code.indent() + if not hasattr(cls, 'abstract') or not cls.abstract: + code('.def(py::init<>())') + code('.def("create", &${cls}Params::create)') + + param_exports = cls.cxx_param_exports + [ + PyBindProperty(k) + for k, v in sorted(cls._params.local.items()) + ] + [ + PyBindProperty("port_%s_connection_count" % port.name) + for port in ports.itervalues() + ] + for exp in param_exports: + exp.export(code, "%sParams" % cls) + + code(';') + code() + code.dedent() + + bases = [ cls._base.cxx_class ] + cls.cxx_bases if cls._base else \ + cls.cxx_bases + if bases: + base_str = ", ".join(bases) + code('py::class_<${{cls.cxx_class}}, ${base_str}>(m, ' \ + '"${py_class_name}")') + else: + code('py::class_<${{cls.cxx_class}}>(m, "${py_class_name}")') + code.indent() + for exp in cls.cxx_exports: + exp.export(code, cls.cxx_class) + code(';') + code.dedent() + code() + code.dedent() + code('}') + code() + code('static EmbeddedPyBind embed_obj("${0}", module_init, "${1}");', + cls, cls._base.type if cls._base else "") + # Generate the C++ declaration (.hh file) for this SimObject's # param struct. Called from src/SConscript. @@ -780,6 +881,14 @@ using std::ptrdiff_t; ''') + + # The base SimObject has a couple of params that get + # automatically set from Python without being declared through + # the normal Param mechanism; we slip them in here (needed + # predecls now, actual declarations below) + if cls == SimObject: + code('''#include <string>''') + # A forward class declaration is sufficient since we are just # declaring a pointer. for ns in class_path[:-1]: @@ -789,18 +898,6 @@ using std::ptrdiff_t; code('} // namespace $ns') code() - # The base SimObject has a couple of params that get - # automatically set from Python without being declared through - # the normal Param mechanism; we slip them in here (needed - # predecls now, actual declarations below) - if cls == SimObject: - code(''' -#ifndef PY_VERSION -struct PyObject; -#endif - -#include <string> -''') for param in params: param.cxx_predecls(code) for port in ports.itervalues(): @@ -832,8 +929,8 @@ struct PyObject; virtual ~SimObjectParams() {} std::string name; - PyObject *pyobj; ''') + for param in params: param.cxx_decl(code) for port in ports.itervalues(): @@ -861,6 +958,47 @@ struct PyObject; def isSimObjectOrVector(value): return False +def cxxMethod(*args, **kwargs): + """Decorator to export C++ functions to Python""" + + def decorate(func): + name = func.func_name + override = kwargs.get("override", False) + cxx_name = kwargs.get("cxx_name", name) + + args, varargs, keywords, defaults = inspect.getargspec(func) + if varargs or keywords: + raise ValueError("Wrapped methods must not contain variable " \ + "arguments") + + # Create tuples of (argument, default) + if defaults: + args = args[:-len(defaults)] + zip(args[-len(defaults):], defaults) + # Don't include self in the argument list to PyBind + args = args[1:] + + + @wraps(func) + def cxx_call(self, *args, **kwargs): + ccobj = self.getCCObject() + return getattr(ccobj, name)(*args, **kwargs) + + @wraps(func) + def py_call(self, *args, **kwargs): + return self.func(*args, **kwargs) + + f = py_call if override else cxx_call + f.__pybind = PyBindMethod(name, cxx_name=cxx_name, args=args) + + return f + + if len(args) == 0: + return decorate + elif len(args) == 1 and len(kwargs) == 0: + return decorate(*args) + else: + raise TypeError("One argument and no kwargs, or only kwargs expected") + # This class holds information about each simobject parameter # that should be displayed on the command line for use in the # configuration system. @@ -921,6 +1059,27 @@ class SimObject(object): void startup(); ''') + cxx_exports = [ + PyBindMethod("init"), + PyBindMethod("initState"), + PyBindMethod("memInvalidate"), + PyBindMethod("memWriteback"), + PyBindMethod("regStats"), + PyBindMethod("resetStats"), + PyBindMethod("regProbePoints"), + PyBindMethod("regProbeListeners"), + PyBindMethod("startup"), + ] + + cxx_param_exports = [ + PyBindProperty("name"), + ] + + @cxxMethod + def loadState(self, cp): + """Load SimObject state from a checkpoint""" + pass + # Returns a dict of all the option strings that can be # generated as command line options for this simobject instance # by tracing all reachable params in the top level instance and @@ -1379,7 +1538,6 @@ class SimObject(object): cc_params_struct = getattr(m5.internal.params, '%sParams' % self.type) cc_params = cc_params_struct() - cc_params.pyobj = self cc_params.name = str(self) param_names = self._params.keys() @@ -1395,8 +1553,7 @@ class SimObject(object): assert isinstance(value, list) vec = getattr(cc_params, param) assert not len(vec) - for v in value: - vec.append(v) + setattr(cc_params, param, list(value)) else: setattr(cc_params, param, value) @@ -1517,4 +1674,9 @@ def clear(): # __all__ defines the list of symbols that get exported when # 'from config import *' is invoked. Try to keep this reasonably # short to avoid polluting other namespaces. -__all__ = [ 'SimObject' ] +__all__ = [ + 'SimObject', + 'cxxMethod', + 'PyBindMethod', + 'PyBindProperty', +] diff --git a/src/python/m5/event.py b/src/python/m5/event.py index 41daa8d3e..d1aff9e5f 100644 --- a/src/python/m5/event.py +++ b/src/python/m5/event.py @@ -1,3 +1,15 @@ +# Copyright (c) 2017 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. +# # Copyright (c) 2006 The Regents of The University of Michigan # Copyright (c) 2013 Advanced Micro Devices, Inc. # Copyright (c) 2013 Mark D. Hill and David A. Wood @@ -31,24 +43,11 @@ import m5 import _m5.event -from _m5.event import PythonEvent, GlobalSimLoopExitEvent as SimExit +from _m5.event import GlobalSimLoopExitEvent as SimExit +from _m5.event import Event, getEventQueue, setEventQueue mainq = None -def create(obj, priority=None): - if priority is None: - priority = Event.Default_Pri - return PythonEvent(obj, priority) - - -# As a reminder, priorities found in sim/eventq.hh are stuck into the -# Event class by swig -class Event(PythonEvent): - def __init__(self, priority=None): - if priority is None: - priority = Event.Default_Pri - super(Event, self).__init__(self, priority) - class ProgressEvent(Event): def __init__(self, eventq, period): super(ProgressEvent, self).__init__() @@ -60,10 +59,4 @@ class ProgressEvent(Event): print "Progress! Time now %fs" % (m5.curTick()/1e12) self.eventq.schedule(self, m5.curTick() + self.period) -def getEventQueue(index): - return _m5.event.getEventQueue(index) - -def setEventQueue(eventq): - _m5.event.curEventQueue(eventq) - -__all__ = [ 'create', 'Event', 'ProgressEvent', 'SimExit', 'mainq' ] +__all__ = [ 'Event', 'ProgressEvent', 'SimExit', 'mainq' ] diff --git a/src/python/m5/internal/params.py b/src/python/m5/internal/params.py index 2d3f7c1ca..ef94ad447 100644 --- a/src/python/m5/internal/params.py +++ b/src/python/m5/internal/params.py @@ -1,3 +1,15 @@ +# Copyright (c) 2017 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. +# # Copyright (c) 2010 The Hewlett-Packard Development Company # All rights reserved. # @@ -26,12 +38,9 @@ # # Authors: Nathan Binkert -try: - modules = __loader__.modules -except NameError: - modules = { } +import inspect +import _m5 -for module in modules.iterkeys(): - if module.startswith('_m5.param_') or \ - module.startswith('_m5.enum_'): - exec "from %s import *" % module +for name, module in inspect.getmembers(_m5): + if name.startswith('param_') or name.startswith('enum_'): + exec "from _m5.%s import *" % name diff --git a/src/python/m5/params.py b/src/python/m5/params.py index ae2b74a23..506fb8c8d 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2014 ARM Limited +# Copyright (c) 2012-2014, 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -102,6 +102,10 @@ class ParamValue(object): def cxx_predecls(cls, code): pass + @classmethod + def pybind_predecls(cls, code): + cls.cxx_predecls(code) + # Generate the code needed as a prerequisite for including a # reference to a C++ object of this type in a SWIG .i file. # Typically generates one or more %import or %include statements. @@ -222,6 +226,9 @@ class ParamDesc(object): code('#include <cstddef>') self.ptype.cxx_predecls(code) + def pybind_predecls(self, code): + self.ptype.pybind_predecls(code) + def swig_predecls(self, code): self.ptype.swig_predecls(code) @@ -408,6 +415,10 @@ class VectorParamDesc(ParamDesc): code('#include <vector>') self.ptype.cxx_predecls(code) + def pybind_predecls(self, code): + code('#include <vector>') + self.ptype.pybind_predecls(code) + def cxx_decl(self, code): code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};') @@ -792,6 +803,11 @@ class AddrRange(ParamValue): code('#include "base/addr_range.hh"') @classmethod + def pybind_predecls(cls, code): + Addr.pybind_predecls(code) + code('#include "base/addr_range.hh"') + + @classmethod def swig_predecls(cls, code): Addr.swig_predecls(code) @@ -941,7 +957,7 @@ class EthernetAddr(ParamValue): return self def getValue(self): - from m5.internal.params import EthAddr + from _m5.net import EthAddr return EthAddr(self.value) def __str__(self): @@ -1007,7 +1023,7 @@ class IpAddress(ParamValue): raise TypeError, "invalid ip address %#08x" % self.ip def getValue(self): - from m5.internal.params import IpAddress + from _m5.net import IpAddress return IpAddress(self.ip) # When initializing an IpNetmask, pass in an existing IpNetmask, a string of @@ -1086,7 +1102,7 @@ class IpNetmask(IpAddress): raise TypeError, "invalid netmask %d" % netmask def getValue(self): - from m5.internal.params import IpNetmask + from _m5.net import IpNetmask return IpNetmask(self.ip, self.netmask) # When initializing an IpWithPort, pass in an existing IpWithPort, a string of @@ -1164,7 +1180,7 @@ class IpWithPort(IpAddress): raise TypeError, "invalid port %d" % self.port def getValue(self): - from m5.internal.params import IpWithPort + from _m5.net import IpWithPort return IpWithPort(self.ip, self.port) time_formats = [ "%a %b %d %H:%M:%S %Z %Y", @@ -1224,30 +1240,10 @@ class Time(ParamValue): return value def getValue(self): - from m5.internal.params import tm - - c_time = tm() - py_time = self.value - - # UNIX is years since 1900 - c_time.tm_year = py_time.tm_year - 1900; - - # Python starts at 1, UNIX starts at 0 - c_time.tm_mon = py_time.tm_mon - 1; - c_time.tm_mday = py_time.tm_mday; - c_time.tm_hour = py_time.tm_hour; - c_time.tm_min = py_time.tm_min; - c_time.tm_sec = py_time.tm_sec; + from _m5.core import tm + import calendar - # Python has 0 as Monday, UNIX is 0 as sunday - c_time.tm_wday = py_time.tm_wday + 1 - if c_time.tm_wday > 6: - c_time.tm_wday -= 7; - - # Python starts at 1, Unix starts at 0 - c_time.tm_yday = py_time.tm_yday - 1; - - return c_time + return tm.gmtime(calendar.timegm(self.value)) def __str__(self): return time.asctime(self.value) @@ -1375,6 +1371,40 @@ $wrapper $wrapper_name { code('} // namespace $wrapper_name') code.dedent(1) + def pybind_def(cls, code): + name = cls.__name__ + wrapper_name = cls.wrapper_name + enum_name = cls.__name__ if cls.enum_name is None else cls.enum_name + + code('''#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include <sim/init.hh> + +namespace py = pybind11; + +static void +module_init(py::module &m_internal) +{ + py::module m = m_internal.def_submodule("enum_${name}"); + + py::enum_<${wrapper_name}::${enum_name}>(m, "enum_${name}") +''') + + code.indent() + code.indent() + for val in cls.vals: + code('.value("${val}", ${wrapper_name}::${val})') + code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})') + code('.export_values()') + code(';') + code.dedent() + + code('}') + code.dedent() + code() + code('static EmbeddedPyBind embed_enum("enum_${name}", module_init);') + def swig_decl(cls, code): name = cls.__name__ code('''\ @@ -1435,7 +1465,9 @@ class Enum(ParamValue): code('}') def getValue(self): - return int(self.map[self.value]) + import m5.internal.params + e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__) + return e(self.map[self.value]) def __str__(self): return self.value @@ -2040,6 +2072,9 @@ class Port(object): def cxx_predecls(self, code): pass + def pybind_predecls(self, code): + cls.cxx_predecls(self, code) + # Declare an unsigned int with the same name as the port, that # will eventually hold the number of connected ports (and thus the # number of elements for a VectorPort). diff --git a/src/python/_m5/__init__.py b/src/python/m5/util/pybind.py index d3ac65e12..003c233b1 100644 --- a/src/python/_m5/__init__.py +++ b/src/python/m5/util/pybind.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 ARM Limited +# Copyright (c) 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -35,5 +35,51 @@ # # Authors: Andreas Sandberg -# This is a place holder to create a package for generated code. Don't -# add any Python code in this name space. +from abc import * + +class PyBindExport(object): + __metaclass__ = ABCMeta + + @abstractmethod + def export(self, code, cname): + pass + +class PyBindProperty(PyBindExport): + def __init__(self, name, cxx_name=None, writable=True): + self.name = name + self.cxx_name = cxx_name if cxx_name else name + self.writable = writable + + def export(self, code, cname): + export = "def_readwrite" if self.writable else "def_readonly" + code('.${export}("${{self.name}}", &${cname}::${{self.cxx_name}})') + +class PyBindMethod(PyBindExport): + def __init__(self, name, cxx_name=None, args=None): + self.name = name + self.cxx_name = cxx_name if cxx_name else name + self.args = args + + def _conv_arg(self, value): + if isinstance(value, bool): + return "true" if value else "false" + elif isinstance(value, float, int): + return repr(value) + else: + raise TypeError("Unsupported PyBind default value type") + + def export(self, code, cname): + if self.args: + def get_arg_decl(arg): + if isinstance(arg, tuple): + name, default = arg + return 'py::arg("%s") = %s' % ( + name, self._conv_arg(default)) + else: + return 'py::arg("%s")' % arg + + code('.def("${{self.name}}", &${cname}::${{self.name}}, ') + code(' ' + \ + ', '.join([ get_arg_decl(a) for a in self.args ]) + ')') + else: + code('.def("${{self.name}}", &${cname}::${{self.cxx_name}})') diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc new file mode 100644 index 000000000..9e97df2b7 --- /dev/null +++ b/src/python/pybind11/core.cc @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2017 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. + * + * Copyright (c) 2010 Advanced Micro Devices, Inc. + * Copyright (c) 2006 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. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Gabe Black + * Andreas Sandberg + */ + +#include "pybind11/pybind11.h" + +#include <ctime> + +#include "base/addr_range.hh" +#include "base/inet.hh" +#include "base/misc.hh" +#include "base/random.hh" +#include "base/socket.hh" +#include "base/types.hh" +#include "sim/core.hh" +#include "sim/drain.hh" +#include "sim/serialize.hh" +#include "sim/sim_object.hh" + +namespace py = pybind11; + +/** Resolve a SimObject name using the Pybind configuration */ +class PybindSimObjectResolver : public SimObjectResolver +{ + SimObject *resolveSimObject(const std::string &name); +}; + +PybindSimObjectResolver pybindSimObjectResolver; + +SimObject * +PybindSimObjectResolver::resolveSimObject(const std::string &name) +{ + // TODO + py::module m = py::module::import("m5.SimObject"); + auto f = m.attr("resolveSimObject"); + + return f(name).cast<SimObject *>(); +} + +extern const char *compileDate; + +#ifdef DEBUG +const bool flag_DEBUG = true; +#else +const bool flag_DEBUG = false; +#endif +#ifdef NDEBUG +const bool flag_NDEBUG = true; +#else +const bool flag_NDEBUG = false; +#endif +const bool flag_TRACING_ON = TRACING_ON; + +static void +init_drain(py::module &m_native) +{ + py::module m = m_native.def_submodule("drain"); + + py::enum_<DrainState>(m, "DrainState") + .value("Running", DrainState::Running) + .value("Draining", DrainState::Draining) + .value("Drained", DrainState::Drained) + ; + + py::class_<Drainable, std::unique_ptr<Drainable, py::nodelete>>( + m, "Drainable") + .def("drainState", &Drainable::drainState) + .def("notifyFork", &Drainable::notifyFork) + ; + + // The drain manager is a singleton with a private + // destructor. Disable deallocation from the Python binding. + py::class_<DrainManager, std::unique_ptr<DrainManager, py::nodelete>>( + m, "DrainManager") + .def("tryDrain", &DrainManager::tryDrain) + .def("resume", &DrainManager::resume) + .def("preCheckpointRestore", &DrainManager::preCheckpointRestore) + .def("isDrained", &DrainManager::isDrained) + .def("state", &DrainManager::state) + .def("signalDrainDone", &DrainManager::signalDrainDone) + .def_static("instance", &DrainManager::instance, + py::return_value_policy::reference) + ; +} + +static void +init_serialize(py::module &m_native) +{ + py::module m = m_native.def_submodule("serialize"); + + py::class_<Serializable>(m, "Serializable") + ; + + py::class_<CheckpointIn>(m, "CheckpointIn") + ; +} + +static void +init_range(py::module &m_native) +{ + py::module m = m_native.def_submodule("range"); + + py::class_<AddrRange>(m, "AddrRange") + .def(py::init<>()) + .def(py::init<Addr &, Addr &>()) + .def(py::init<const std::vector<AddrRange> &>()) + .def(py::init<Addr, Addr, uint8_t, uint8_t, uint8_t, uint8_t>()) + + .def("__str__", &AddrRange::to_string) + + .def("interleaved", &AddrRange::interleaved) + .def("hashed", &AddrRange::hashed) + .def("granularity", &AddrRange::granularity) + .def("stripes", &AddrRange::stripes) + .def("size", &AddrRange::size) + .def("valid", &AddrRange::valid) + .def("start", &AddrRange::start) + .def("end", &AddrRange::end) + .def("mergesWith", &AddrRange::mergesWith) + .def("intersects", &AddrRange::intersects) + .def("isSubset", &AddrRange::isSubset) + ; + + m.def("RangeEx", &RangeEx); + m.def("RangeIn", &RangeIn); + m.def("RangeSize", &RangeSize); +} + +static void +init_net(py::module &m_native) +{ + py::module m = m_native.def_submodule("net"); + + py::class_<Net::EthAddr>(m, "EthAddr") + .def(py::init<>()) + .def(py::init<const std::string &>()) + ; + + py::class_<Net::IpAddress>(m, "IpAddress") + .def(py::init<>()) + .def(py::init<uint32_t>()) + ; + + py::class_<Net::IpNetmask, Net::IpAddress>(m, "IpNetmask") + .def(py::init<>()) + .def(py::init<uint32_t, uint8_t>()) + ; + + py::class_<Net::IpWithPort, Net::IpAddress>(m, "IpWithPort") + .def(py::init<>()) + .def(py::init<uint32_t, uint16_t>()) + ; +} + +void +pybind_init_core(py::module &m_native) +{ + py::module m_core = m_native.def_submodule("core"); + + py::class_<Cycles>(m_core, "Cycles") + .def(py::init<>()) + .def(py::init<uint64_t>()) + .def("__int__", &Cycles::operator uint64_t) + .def("__add__", &Cycles::operator+) + .def("__sub__", &Cycles::operator-) + ; + + py::class_<tm>(m_core, "tm") + .def_static("gmtime", [](std::time_t t) { return *std::gmtime(&t); }) + .def_readwrite("tm_sec", &tm::tm_sec) + .def_readwrite("tm_min", &tm::tm_min) + .def_readwrite("tm_hour", &tm::tm_hour) + .def_readwrite("tm_mday", &tm::tm_mday) + .def_readwrite("tm_mon", &tm::tm_mon) + .def_readwrite("tm_wday", &tm::tm_wday) + .def_readwrite("tm_yday", &tm::tm_yday) + .def_readwrite("tm_isdst", &tm::tm_isdst) + ; + + py::enum_<Logger::LogLevel>(m_core, "LogLevel") + .value("PANIC", Logger::PANIC) + .value("FATAL", Logger::FATAL) + .value("WARN", Logger::WARN) + .value("INFO", Logger::INFO) + .value("HACK", Logger::HACK) + ; + + m_core + .def("setLogLevel", &Logger::setLevel) + .def("setOutputDir", &setOutputDir) + .def("doExitCleanup", &doExitCleanup) + + .def("disableAllListeners", &ListenSocket::disableAll) + .def("listenersDisabled", &ListenSocket::allDisabled) + .def("seedRandom", [](uint64_t seed) { random_mt.init(seed); }) + + + .def("setClockFrequency", &setClockFrequency) + .def("curTick", curTick) + ; + + /* TODO: These should be read-only */ + m_core.attr("compileDate") = py::cast(compileDate); + + m_core.attr("flag_DEBUG") = py::cast(flag_DEBUG); + m_core.attr("flag_DEBUG") = py::cast(flag_DEBUG); + m_core.attr("flag_NDEBUG") = py::cast(flag_NDEBUG); + m_core.attr("flag_TRACING_ON") = py::cast(flag_TRACING_ON); + + m_core.attr("MaxTick") = py::cast(MaxTick); + + /* + * Serialization helpers + */ + m_core + .def("serializeAll", &Serializable::serializeAll) + .def("unserializeGlobals", &Serializable::unserializeGlobals) + .def("getCheckpoint", [](const std::string &cpt_dir) { + return new CheckpointIn(cpt_dir, pybindSimObjectResolver); + }) + + ; + + + init_drain(m_native); + init_serialize(m_native); + init_range(m_native); + init_net(m_native); +} + diff --git a/src/python/pybind11/debug.cc b/src/python/pybind11/debug.cc new file mode 100644 index 000000000..8fcd0cdbc --- /dev/null +++ b/src/python/pybind11/debug.cc @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017 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. + * + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2010 The Hewlett-Packard Development Company + * 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. + * + * Authors: Nathan Binkert + * Andreas Sandberg + */ + +#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include <map> +#include <vector> + +#include "base/debug.hh" +#include "base/output.hh" +#include "base/trace.hh" +#include "sim/debug.hh" + +namespace py = pybind11; + +namespace Debug { +extern int allFlagsVersion; +} + +static void +output(const char *filename) +{ + OutputStream *file_stream = simout.find(filename); + + if (!file_stream) + file_stream = simout.create(filename); + + Trace::setDebugLogger(new Trace::OstreamLogger(*file_stream->stream())); +} + +static void +ignore(const char *expr) +{ + ObjectMatch ignore(expr); + + Trace::getDebugLogger()->setIgnore(ignore); +} + +void +pybind_init_debug(py::module &m_native) +{ + py::module m_debug = m_native.def_submodule("debug"); + + m_debug + .def("getAllFlagsVersion", []() { return Debug::allFlagsVersion; }) + .def("allFlags", &Debug::allFlags, py::return_value_policy::reference) + .def("findFlag", &Debug::findFlag) + .def("setDebugFlag", &setDebugFlag) + .def("clearDebugFlag", &clearDebugFlag) + .def("dumpDebugFlags", &dumpDebugFlags) + + .def("schedBreak", &schedBreak) + .def("setRemoteGDBPort", &setRemoteGDBPort) + ; + + py::class_<Debug::Flag> c_flag(m_debug, "Flag"); + c_flag + .def("name", &Debug::Flag::name) + .def("desc", &Debug::Flag::desc) + .def("kids", &Debug::Flag::kids) + .def("enable", &Debug::Flag::enable) + .def("disable", &Debug::Flag::disable) + .def("sync", &Debug::Flag::sync) + ; + + py::class_<Debug::SimpleFlag>(m_debug, "SimpleFlag", c_flag); + py::class_<Debug::CompoundFlag>(m_debug, "CompoundFlag", c_flag); + + + py::module m_trace = m_native.def_submodule("trace"); + m_trace + .def("output", &output) + .def("ignore", &ignore) + .def("enable", &Trace::enable) + .def("disable", &Trace::disable) + ; +} diff --git a/src/python/pybind11/event.cc b/src/python/pybind11/event.cc new file mode 100644 index 000000000..45a2d46a0 --- /dev/null +++ b/src/python/pybind11/event.cc @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2017 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. + * + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2013 Advanced Micro Devices, Inc. + * Copyright (c) 2013 Mark D. Hill and David A. Wood + * 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. + * + * Authors: Nathan Binkert + * Andreas Sandberg + */ + +#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include "sim/eventq.hh" +#include "sim/sim_events.hh" +#include "sim/sim_exit.hh" +#include "sim/simulate.hh" + +namespace py = pybind11; + +/** + * PyBind wrapper for Events + * + * We need to wrap the Event class with some Python glue code to + * enable method overrides in Python and memory management. Unlike its + * C++ cousin, PyEvents need to override __call__ instead of + * Event::process(). + * + * Memory management is mostly done using reference counting in + * Python. However, PyBind can't keep track of the reference the event + * queue holds to a scheduled event. We therefore need to inhibit + * deletion and hand over ownership to the event queue in case a + * scheduled event loses all of its Python references. + */ +class PyEvent : public Event +{ + public: + struct Deleter { + void operator()(PyEvent *ev) { + assert(!ev->isAutoDelete()); + if (ev->scheduled()) { + // The event is scheduled, give ownership to the event + // queue. + ev->setFlags(Event::AutoDelete); + } else { + // The event isn't scheduled, hence Python owns it and + // we need to free it here. + delete ev; + } + } + }; + + PyEvent(Event::Priority priority) + : Event(priority) + { } + + void process() override { + if (isAutoDelete()) { + // Ownership of the event was handed over to the event queue + // because the last revference in Python land was GCed. We + // need to claim the object again since we're creating a new + // Python reference. + clearFlags(AutoDelete); + } + + // Call the Python implementation as __call__. This provides a + // slightly more Python-friendly interface. + PYBIND11_OVERLOAD_PURE_NAME(void, PyEvent, "__call__", process); + } +}; + +void +pybind_init_event(py::module &m_native) +{ + py::module m = m_native.def_submodule("event"); + + m.def("simulate", &simulate, + py::arg("ticks") = MaxTick); + m.def("exitSimLoop", &exitSimLoop); + m.def("getEventQueue", []() { return curEventQueue(); }, + py::return_value_policy::reference); + m.def("setEventQueue", [](EventQueue *q) { return curEventQueue(q); }); + m.def("getEventQueue", &getEventQueue, + py::return_value_policy::reference); + + py::class_<EventQueue>(m, "EventQueue") + .def("name", [](EventQueue *eq) { return eq->name(); }) + .def("dump", &EventQueue::dump) + .def("schedule", [](EventQueue *eq, PyEvent *e, Tick t) { + eq->schedule(e, t); + }, py::arg("event"), py::arg("when")) + .def("deschedule", [](EventQueue *eq, PyEvent *e) { + eq->deschedule(e); + }, py::arg("event")) + .def("reschedule", [](EventQueue *eq, PyEvent *e, Tick t, bool alw) { + eq->reschedule(e, t, alw); + }, py::arg("event"), py::arg("tick"), py::arg("always") = false) + ; + + // TODO: Ownership of global exit events has always been a bit + // questionable. We currently assume they are owned by the C++ + // word. This is what the old SWIG code did, but that will result + // in memory leaks. + py::class_<GlobalSimLoopExitEvent, + std::unique_ptr<GlobalSimLoopExitEvent, py::nodelete>>( + m, "GlobalSimLoopExitEvent") + .def("getCause", &GlobalSimLoopExitEvent::getCause) + .def("getCode", &GlobalSimLoopExitEvent::getCode) + ; + + // TODO: We currently export a wrapper class and not the Event + // base class. This wil be problematic if we ever return an event + // from C++. + py::class_<PyEvent, std::unique_ptr<PyEvent, PyEvent::Deleter>> + c_event(m, "Event"); + c_event + .def(py::init<Event::Priority>(), + py::arg("priority") = (int)Event::Default_Pri) + .def("name", &Event::name) + .def("dump", &Event::dump) + .def("scheduled", &Event::scheduled) + .def("squash", &Event::squash) + .def("squashed", &Event::squashed) + .def("isExitEvent", &Event::isExitEvent) + .def("isAutoDelete", &Event::isAutoDelete) + .def("when", &Event::when) + .def("priority", &Event::priority) + ; + +#define PRIO(n) c_event.attr(# n) = py::cast((int)Event::n) + PRIO(Minimum_Pri); + PRIO(Minimum_Pri); + PRIO(Debug_Enable_Pri); + PRIO(Debug_Break_Pri); + PRIO(CPU_Switch_Pri); + PRIO(Delayed_Writeback_Pri); + PRIO(Default_Pri); + PRIO(DVFS_Update_Pri); + PRIO(Serialize_Pri); + PRIO(CPU_Tick_Pri); + PRIO(Stat_Event_Pri); + PRIO(Progress_Event_Pri); + PRIO(Sim_Exit_Pri); + PRIO(Maximum_Pri); +} diff --git a/src/python/swig/serialize.i b/src/python/pybind11/pybind.hh index 2ade6157a..9a0643c5a 100644 --- a/src/python/swig/serialize.i +++ b/src/python/pybind11/pybind.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -37,15 +37,16 @@ * Authors: Andreas Sandberg */ -%module(package="_m5") serialize +#ifndef __PYTHON_PYBIND11_PYBIND_HH__ +#define __PYTHON_PYBIND11_PYBIND_HH__ -%{ -#include "sim/serialize.hh" -%} +#include "pybind11/pybind11.h" -%nodefaultctor Serializable; +void pybind_init_core(pybind11::module &m_native); +void pybind_init_debug(pybind11::module &m_native); -class Serializable -{ - virtual const std::string name() const = 0; -}; +void pybind_init_event(pybind11::module &m_native); +void pybind_init_pyobject(pybind11::module &m_native); +void pybind_init_stats(pybind11::module &m_native); + +#endif diff --git a/src/python/swig/pyobject.cc b/src/python/pybind11/pyobject.cc index 07a2ef864..fe0ecba78 100644 --- a/src/python/swig/pyobject.cc +++ b/src/python/pybind11/pyobject.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 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. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -28,30 +40,27 @@ * Authors: Nathan Binkert */ -#include <Python.h> +#include "pybind11/pybind11.h" #include <string> -#include "base/inifile.hh" -#include "base/output.hh" #include "config/the_isa.hh" #if THE_ISA != NULL_ISA #include "dev/net/etherdevice.hh" +#include "dev/net/etherint.hh" #include "dev/net/etherobject.hh" #endif -#include "python/swig/pyobject.hh" #include "mem/mem_object.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "sim/full_system.hh" -#include "sim/sim_object.hh" -using namespace std; +namespace py = pybind11; #if THE_ISA != NULL_ISA -EtherInt * +static EtherInt * lookupEthPort(SimObject *so, const std::string &name, int i) { EtherObject *eo = dynamic_cast<EtherObject *>(so); @@ -75,7 +84,7 @@ lookupEthPort(SimObject *so, const std::string &name, int i) * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports. * SimObject1 is the master, and SimObject2 is the slave */ -int +static int connectPorts(SimObject *o1, const std::string &name1, int i1, SimObject *o2, const std::string &name2, int i2) { @@ -134,62 +143,10 @@ connectPorts(SimObject *o1, const std::string &name1, int i1, return 1; } -inline IniFile & -inifile() -{ - static IniFile inifile; - return inifile; -} - -/** - * Convert a pointer to the Python object that SWIG wraps around a C++ - * SimObject pointer back to the actual C++ pointer. See main.i. - */ -extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); - -// Python.h is notoriously not const-correct (for 2.4, anyway)... make -// a little define here to reduce the noise and make it easier to -// #ifdef away if Python.h gets fixed. Note there are a couple of -// these in sim/main.cc as well that are handled without this define. -#define PCC(s) const_cast<char *>(s) - -/** Single instance of PythonSimObjectResolver as its action is effectively - * static but SimObjectResolver can use a non-persistent object */ -PythonSimObjectResolver pythonSimObjectResolver; - -SimObject * -PythonSimObjectResolver::resolveSimObject(const string &name) +void +pybind_init_pyobject(py::module &m_native) { - PyObject *module = PyImport_ImportModule(PCC("m5.SimObject")); - if (module == NULL) - panic("Could not import m5.SimObject"); - - PyObject *resolver = - PyObject_GetAttrString(module, PCC("resolveSimObject")); - if (resolver == NULL) { - PyErr_Print(); - panic("resolveSimObject: failed to find resolveSimObject"); - } - - PyObject *ptr = PyObject_CallFunction(resolver, PCC("(s)"), name.c_str()); - if (ptr == NULL) { - PyErr_Print(); - panic("resolveSimObject: failure on call to Python for %s", name); - } - - SimObject *obj = convertSwigSimObjectPtr(ptr); - if (obj == NULL) - panic("resolveSimObject: failure on pointer conversion for %s", name); + py::module m = m_native.def_submodule("pyobject"); - Py_DECREF(module); - Py_DECREF(resolver); - Py_DECREF(ptr); - - return obj; -} - -CheckpointIn * -getCheckpoint(const std::string &cpt_dir) -{ - return new CheckpointIn(cpt_dir, pythonSimObjectResolver); + m.def("connectPorts", &connectPorts); } diff --git a/src/python/pybind11/stats.cc b/src/python/pybind11/stats.cc new file mode 100644 index 000000000..39d9ce873 --- /dev/null +++ b/src/python/pybind11/stats.cc @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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. + * + * Copyright (c) 2006 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. + * + * Authors: Nathan Binkert + * Andreas Sandberg + */ + +#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include "base/statistics.hh" +#include "base/stats/text.hh" +#include "sim/stat_control.hh" +#include "sim/stat_register.hh" + +namespace py = pybind11; + +namespace Stats { + +void +pythonDump() +{ + py::module m = py::module::import("m5.stats"); + m.attr("dump")(); +} + +void +pythonReset() +{ + py::module m = py::module::import("m5.stats"); + m.attr("reset")(); +} + +} + +void +pybind_init_stats(py::module &m_native) +{ + py::module m = m_native.def_submodule("stats"); + + m + .def("initSimStats", &Stats::initSimStats) + .def("initText", &Stats::initText, py::return_value_policy::reference) + .def("registerPythonStatsHandlers", + &Stats::registerPythonStatsHandlers) + .def("schedStatEvent", &Stats::schedStatEvent) + .def("periodicStatDump", &Stats::periodicStatDump) + .def("updateEvents", &Stats::updateEvents) + .def("processResetQueue", &Stats::processResetQueue) + .def("processDumpQueue", &Stats::processDumpQueue) + .def("enable", &Stats::enable) + .def("enabled", &Stats::enabled) + .def("statsList", &Stats::statsList) + ; + + py::class_<Stats::Output>(m, "Output") + .def("begin", &Stats::Output::begin) + .def("end", &Stats::Output::end) + .def("valid", &Stats::Output::valid) + ; + + py::class_<Stats::Info>(m, "Info") + .def_readwrite("name", &Stats::Info::name) + .def_readonly("desc", &Stats::Info::desc) + .def_readonly("id", &Stats::Info::id) + .def_property_readonly("flags", [](const Stats::Info &info) { + return (Stats::FlagsType)info.flags; + }) + .def("check", &Stats::Info::check) + .def("baseCheck", &Stats::Info::baseCheck) + .def("enable", &Stats::Info::enable) + .def("prepare", &Stats::Info::prepare) + .def("reset", &Stats::Info::reset) + .def("zero", &Stats::Info::zero) + .def("visit", &Stats::Info::visit) + ; +} diff --git a/src/python/swig/core.i b/src/python/swig/core.i deleted file mode 100644 index 8b734b940..000000000 --- a/src/python/swig/core.i +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - * Steve Reinhardt - */ - -%module(package="_m5") core - -%{ -#include "base/misc.hh" -#include "base/random.hh" -#include "base/socket.hh" -#include "base/types.hh" -#include "python/swig/pyobject.hh" -#include "sim/core.hh" - -extern const char *compileDate; - -#ifdef DEBUG -const bool flag_DEBUG = true; -#else -const bool flag_DEBUG = false; -#endif -#ifdef NDEBUG -const bool flag_NDEBUG = true; -#else -const bool flag_NDEBUG = false; -#endif -const bool flag_TRACING_ON = TRACING_ON; - -inline void disableAllListeners() { ListenSocket::disableAll(); } - -inline bool listenersDisabled() { return ListenSocket::allDisabled(); } - -inline void -seedRandom(uint64_t seed) -{ - random_mt.init(seed); -} - -%} - -%include <std_string.i> -%include <stdint.i> - -%include "base/types.hh" - -void setOutputDir(const std::string &dir); -void doExitCleanup(); -void disableAllListeners(); -bool listenersDisabled(); -void seedRandom(uint64_t seed); - -%immutable compileDate; -char *compileDate; -const bool flag_DEBUG; -const bool flag_NDEBUG; -const bool flag_TRACING_ON; - -void setClockFrequency(Tick ticksPerSecond); - -Tick curTick(); - -class Checkpoint; - -void serializeAll(const std::string &cpt_dir); -CheckpointIn *getCheckpoint(const std::string &cpt_dir); -void unserializeGlobals(CheckpointIn &cp); - -class Logger -{ - public: - enum LogLevel { - PANIC = 0, - FATAL, - WARN, - INFO, - HACK, - NUM_LOG_LEVELS, - }; - - static void setLevel(LogLevel ll); - - private: - Logger(); -}; diff --git a/src/python/swig/debug.i b/src/python/swig/debug.i deleted file mode 100644 index b05b66e47..000000000 --- a/src/python/swig/debug.i +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2006 The Regents of The University of Michigan - * Copyright (c) 2010 The Hewlett-Packard Development Company - * 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") debug - -%{ -#include <cassert> -#include <map> -#include <string> -#include <vector> - -#include "base/debug.hh" -#include "base/types.hh" -#include "sim/debug.hh" - -using namespace std; - -typedef map<string, Debug::Flag *> FlagsMap; -typedef vector<Debug::Flag *> FlagsVec; - -namespace Debug { -extern int allFlagsVersion; -FlagsMap &allFlags(); -} - -inline int -getAllFlagsVersion() -{ - return Debug::allFlagsVersion; -} - -inline FlagsVec -getAllFlags() -{ - FlagsMap &flagsMap = Debug::allFlags(); - - FlagsVec flags(flagsMap.size()); - - int index = 0; - FlagsMap::iterator i = flagsMap.begin(); - FlagsMap::iterator end = flagsMap.end(); - for (; i != end; ++i) { - assert(index < flags.size()); - flags[index++] = i->second; - } - - return flags; -} - -%} - -%ignore Debug::SimpleFlag::operator!; - -%include <std_string.i> -%include <std_vector.i> -%include <stdint.i> - -%include "base/debug.hh" -%include "base/types.hh" -%include "sim/debug.hh" - -%template(AllFlags) std::vector<Debug::Flag *>; - -int getAllFlagsVersion(); -std::vector<Debug::Flag *> getAllFlags(); diff --git a/src/python/swig/drain.i b/src/python/swig/drain.i deleted file mode 100644 index 8bd7ef9ef..000000000 --- a/src/python/swig/drain.i +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2012 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. - * - * Authors: Andreas Sandberg - */ - -%module(package="_m5") drain - -%{ -#include "sim/drain.hh" -%} - -%nodefaultctor Drainable; - -%include "sim/drain.hh" diff --git a/src/python/swig/event.i b/src/python/swig/event.i deleted file mode 100644 index 464be8289..000000000 --- a/src/python/swig/event.i +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2006 The Regents of The University of Michigan - * Copyright (c) 2013 Advanced Micro Devices, Inc. - * Copyright (c) 2013 Mark D. Hill and David A. Wood - * 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") event - -%{ -#include "base/types.hh" -#include "python/swig/pyevent.hh" -#include "sim/eventq_impl.hh" -#include "sim/sim_events.hh" -#include "sim/sim_exit.hh" -#include "sim/simulate.hh" -%} - -%import "python/swig/serialize.i" - -#pragma SWIG nowarn=350,351 - -%extend EventQueue { - void - schedule(Event *event, Tick when) - { - // Any python event that are scheduled must have their - // internal object's refcount incremented so that the object - // sticks around while it is in the event queue. - PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event); - if (pyevent) - pyevent->incref(); - $self->schedule(event, when); - } - - void - deschedule(Event *event) - { - $self->deschedule(event); - - // Now that we're removing the python object from the event - // queue, we need to decrement its reference count. - PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event); - if (pyevent) - pyevent->decref(); - } -} - -%typemap(out) PythonEvent* { - result->object = $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PythonEvent, SWIG_POINTER_NEW); -} - -%ignore EventQueue::schedule; -%ignore EventQueue::deschedule; - -%include <std_string.i> -%include <stdint.i> - -%include "base/types.hh" -%include "sim/eventq.hh" - -// This must follow eventq.hh -%include "python/swig/pyevent.hh" - -// minimal definition of SimExitEvent interface to wrap -class GlobalSimLoopExitEvent -{ - public: - std::string getCause(); - int getCode(); - GlobalSimLoopExitEvent(Tick when, const std::string &_cause, int c, - Tick _repeat = 0); -}; - -%exception simulate { - $action - if (!result) { - return NULL; - } -} - -GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick); -void exitSimLoop(const std::string &message, int exit_code); -void curEventQueue( EventQueue *); -EventQueue *getEventQueue(uint32_t index); diff --git a/src/python/swig/inet.i b/src/python/swig/inet.i deleted file mode 100644 index 144b3dbac..000000000 --- a/src/python/swig/inet.i +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006 The Regents of The University of Michigan - * Copyright (c) 2010 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: 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. - * - * Authors: Nathan Binkert - * Gabe Black - */ - -%{ -#include "base/inet.hh" -%} - -%import <std_string.i> -%import <stdint.i> - -namespace Net { -struct EthAddr -{ - EthAddr(); - EthAddr(const uint8_t ea[6]); - EthAddr(const std::string &addr); -}; - -struct IpAddress -{ - IpAddress(); - IpAddress(const uint32_t __addr); -}; - -struct IpNetmask : IpAddress -{ - IpNetmask(); - IpNetmask(const uint32_t __addr, const uint8_t __netmask); -}; - -struct IpWithPort : IpAddress -{ - IpWithPort(); - IpWithPort(const uint32_t __addr, const uint16_t __port); -}; - -} - diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc deleted file mode 100644 index 39c57d116..000000000 --- a/src/python/swig/pyevent.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -#include <Python.h> - -#include "python/swig/pyevent.hh" - -#include "base/misc.hh" -#include "sim/async.hh" -#include "sim/eventq.hh" - -PythonEvent::PythonEvent(PyObject *code, Priority priority) - : Event(priority), eventCode(code) -{ - if (code == NULL) - panic("Passed in invalid object"); -} - -PythonEvent::~PythonEvent() -{ -} - -void -PythonEvent::process() -{ - PyObject *args = PyTuple_New(0); - PyObject *result = PyObject_Call(eventCode, args, NULL); - Py_DECREF(args); - - if (result) { - // Nothing to do just decrement the reference count - Py_DECREF(result); - } else { - // Somethign should be done to signal back to the main interpreter - // that there's been an exception. - async_event = true; - async_exception = true; - /* Wake up some event queue to handle event */ - getEventQueue(0)->wakeup(); - } - - // Since the object has been removed from the event queue, its - // reference count must be decremented. - Py_DECREF(object); -} diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh deleted file mode 100644 index 9f2ce9ee7..000000000 --- a/src/python/swig/pyevent.hh +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -#ifndef __PYTHON_SWIG_PYEVENT_HH__ -#define __PYTHON_SWIG_PYEVENT_HH__ - -#include <Python.h> - -#include "sim/eventq.hh" -#include "sim/init.hh" -#include "sim/sim_events.hh" - -class PythonEvent : public Event -{ - private: - PyObject *eventCode; // PyObject to call to perform event - public: - PyObject *object; // PyObject wrapping this PythonEvent - - PythonEvent(PyObject *obj, Event::Priority priority); - ~PythonEvent(); - - void incref() { Py_INCREF(object); } - void decref() { Py_DECREF(object); } - - virtual void process(); -}; - -#endif // __PYTHON_SWIG_PYEVENT_HH__ diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh deleted file mode 100644 index 6147e4bd9..000000000 --- a/src/python/swig/pyobject.hh +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -#include <Python.h> - -#include "base/types.hh" -#include "dev/net/etherint.hh" -#include "sim/serialize.hh" -#include "sim/sim_object.hh" - -extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); - -/** Resolve a SimObject name using the Python configuration */ -class PythonSimObjectResolver : public SimObjectResolver -{ - SimObject *resolveSimObject(const std::string &name); -}; - -EtherInt * lookupEthPort(SimObject *so, const std::string &name, int i); - -/** - * Connect the described MemObject ports. Called from Python via SWIG. - */ -int connectPorts(SimObject *o1, const std::string &name1, int i1, - SimObject *o2, const std::string &name2, int i2); - - -inline void -serializeAll(const std::string &cpt_dir) -{ - Serializable::serializeAll(cpt_dir); -} - -CheckpointIn * -getCheckpoint(const std::string &cpt_dir); - -inline void -unserializeGlobals(CheckpointIn &cp) -{ - Serializable::unserializeGlobals(cp); -} diff --git a/src/python/swig/pyobject.i b/src/python/swig/pyobject.i deleted file mode 100644 index d4601d6a9..000000000 --- a/src/python/swig/pyobject.i +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") pyobject - -%{ -#include "python/swig/pyobject.hh" -%} - -// import these files for SWIG to wrap -%include <std_string.i> -%include <stdint.i> - -int connectPorts(SimObject *o1, const std::string &name1, int i1, - SimObject *o2, const std::string &name2, int i2); - -%wrapper %{ -// Convert a pointer to the Python object that SWIG wraps around a -// C++ SimObject pointer back to the actual C++ pointer. -SimObject * -convertSwigSimObjectPtr(PyObject *pyObj) -{ - SimObject *so; - if (SWIG_ConvertPtr(pyObj, (void **) &so, SWIGTYPE_p_SimObject, 0) == -1) - return NULL; - return so; -} -%} diff --git a/src/python/swig/range.i b/src/python/swig/range.i deleted file mode 100644 index 7ee27679f..000000000 --- a/src/python/swig/range.i +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") range - -%{ -#include "base/types.hh" -#include "base/addr_range.hh" -%} - -%include <stdint.i> - -%rename(assign) *::operator=; -%include "base/types.hh" -%include "base/addr_range.hh" diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i deleted file mode 100644 index c22cd45a3..000000000 --- a/src/python/swig/stats.i +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") stats - -%include <std_list.i> -%include <std_string.i> -%include <std_vector.i> -%include <stdint.i> - -%{ -#include "base/stats/text.hh" -#include "base/stats/types.hh" -#include "base/callback.hh" -#include "base/misc.hh" -#include "base/statistics.hh" -#include "sim/core.hh" -#include "sim/stat_control.hh" -#include "sim/stat_register.hh" - -namespace Stats { - -inline FlagsType -Stats_Info_flags_get(Info *info) -{ - return info->flags; -} - -inline void -Stats_Info_flags_set(Info *info, FlagsType flags) -{ - info->flags = flags; -} - -inline char * -PCC(const char *string) -{ - return const_cast<char *>(string); -} - -void -call_module_function(const char *module_name, const char *func_name) -{ - PyObject *module = PyImport_ImportModule(PCC(module_name)); - if (module == NULL) - panic("Could not import %s", module); - - PyObject *result = PyObject_CallMethod(module, PCC(func_name), PCC("")); - if (result == NULL) { - PyErr_Print(); - panic("failure on call to function %s", func_name); - } - - Py_DECREF(module); - Py_DECREF(result); -} - -void -pythonDump() -{ - call_module_function("m5.stats", "dump"); -} - -void -pythonReset() -{ - call_module_function("m5.stats", "reset"); -} - -} // namespace Stats -%} - -%extend Stats::Info { - short flags; -} - -%ignore Stats::Info::flags; - -%import "base/stats/types.hh" -%import "base/types.hh" - -%include "base/stats/info.hh" -%include "base/stats/output.hh" - -namespace std { -%template(list_info) list<Stats::Info *>; -%template(vector_double) vector<double>; -%template(vector_string) vector<string>; -%template(vector_DistData) vector<Stats::DistData>; -} - -namespace Stats { - -void initSimStats(); -Output *initText(const std::string &filename, bool desc); - -void registerPythonStatsHandlers(); - -void schedStatEvent(bool dump, bool reset, - Tick when = curTick(), Tick repeat = 0); - -void periodicStatDump(Tick period = 0); - -void updateEvents(); - -void processResetQueue(); -void processDumpQueue(); -void enable(); -bool enabled(); - -std::list<Info *> &statsList(); - -} // namespace Stats diff --git a/src/python/swig/time.i b/src/python/swig/time.i deleted file mode 100644 index 9bbad081a..000000000 --- a/src/python/swig/time.i +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -%{ -#include <sys/time.h> -%} - -struct tm { - int tm_sec; /* seconds after the minute [0-60] */ - int tm_min; /* minutes after the hour [0-59] */ - int tm_hour; /* hours since midnight [0-23] */ - int tm_mday; /* day of the month [1-31] */ - int tm_mon; /* months since January [0-11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday [0-6] */ - int tm_yday; /* days since January 1 [0-365] */ -}; diff --git a/src/python/swig/trace.i b/src/python/swig/trace.i deleted file mode 100644 index 9ea60b816..000000000 --- a/src/python/swig/trace.i +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2006 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") trace - -%{ -#include "base/trace.hh" -#include "base/types.hh" -#include "base/output.hh" - -inline void -output(const char *filename) -{ - OutputStream *file_stream = simout.find(filename); - - if (!file_stream) - file_stream = simout.create(filename); - - Trace::setDebugLogger(new Trace::OstreamLogger(*file_stream->stream())); -} - -inline void -ignore(const char *expr) -{ - ObjectMatch ignore(expr); - - Trace::getDebugLogger()->setIgnore(ignore); -} - -inline void enable() { Trace::enable(); } -inline void disable() { Trace::disable(); } -%} - -extern void output(const char *string); -extern void ignore(const char *expr); -extern void enable(); -extern void disable(); diff --git a/src/sim/Process.py b/src/sim/Process.py index 743e5247c..2ffc51a33 100644 --- a/src/sim/Process.py +++ b/src/sim/Process.py @@ -26,13 +26,18 @@ # # Authors: Nathan Binkert -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * from m5.proxy import * class Process(SimObject): type = 'Process' cxx_header = "sim/process.hh" + + @cxxMethod + def map(self, vaddr, paddr, size, cacheable=False): + pass + input = Param.String('cin', "filename for stdin") output = Param.String('cout', 'filename for stdout') errout = Param.String('cerr', 'filename for stderr') diff --git a/src/sim/System.py b/src/sim/System.py index e3e42d862..53377989d 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -28,7 +28,7 @@ # Authors: Nathan Binkert # Rick Strong -from m5.SimObject import SimObject +from m5.SimObject import * from m5.defines import buildEnv from m5.params import * from m5.proxy import * @@ -44,12 +44,10 @@ class System(MemObject): cxx_header = "sim/system.hh" system_port = MasterPort("System port") - @classmethod - def export_methods(cls, code): - code(''' - Enums::MemoryMode getMemoryMode() const; - void setMemoryMode(Enums::MemoryMode mode); -''') + cxx_exports = [ + PyBindMethod("getMemoryMode"), + PyBindMethod("setMemoryMode"), + ] memories = VectorParam.AbstractMemory(Self.all, "All memories in the system") diff --git a/src/sim/init.cc b/src/sim/init.cc index f2395eec4..33cd4040f 100644 --- a/src/sim/init.cc +++ b/src/sim/init.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012, 2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -56,6 +56,7 @@ #include "base/misc.hh" #include "base/types.hh" #include "config/have_protobuf.hh" +#include "python/pybind11/pybind.hh" #include "sim/async.hh" #include "sim/core.hh" @@ -65,6 +66,7 @@ #endif using namespace std; +namespace py = pybind11; // The python library is totally messed up with respect to constness, // so make a simple macro to make life a little easier @@ -184,10 +186,87 @@ EmbeddedSwig::initAll() _Py_PackageContext = old_context; } +EmbeddedPyBind::EmbeddedPyBind(const char *_name, + void (*init_func)(py::module &), + const char *_base) + : initFunc(init_func), registered(false), name(_name), base(_base) +{ + getMap()[_name] = this; +} + +EmbeddedPyBind::EmbeddedPyBind(const char *_name, + void (*init_func)(py::module &)) + : initFunc(init_func), registered(false), name(_name), base("") +{ + getMap()[_name] = this; +} + +void +EmbeddedPyBind::init(py::module &m) +{ + if (!registered) { + initFunc(m); + registered = true; + } else { + cprintf("Warning: %s already registered.\n", name); + } +} + +bool +EmbeddedPyBind::depsReady() const +{ + return base.empty() || getMap()[base]->registered; +} + +std::map<std::string, EmbeddedPyBind *> & +EmbeddedPyBind::getMap() +{ + static std::map<std::string, EmbeddedPyBind *> objs; + return objs; +} + +void +EmbeddedPyBind::initAll() +{ + std::list<EmbeddedPyBind *> pending; + + py::module m_m5 = py::module("_m5"); + m_m5.attr("__package__") = py::cast("_m5"); + + pybind_init_core(m_m5); + pybind_init_debug(m_m5); + + pybind_init_event(m_m5); + pybind_init_pyobject(m_m5); + pybind_init_stats(m_m5); + + for (auto &kv : getMap()) { + auto &obj = kv.second; + if (obj->base.empty()) { + obj->init(m_m5); + } else { + pending.push_back(obj); + } + } + + while (!pending.empty()) { + for (auto it = pending.begin(); it != pending.end(); ) { + EmbeddedPyBind &obj = **it; + if (obj.depsReady()) { + obj.init(m_m5); + it = pending.erase(it); + } else { + ++it; + } + } + } +} + int initM5Python() { EmbeddedSwig::initAll(); + EmbeddedPyBind::initAll(); return EmbeddedPython::initAll(); } diff --git a/src/sim/init.hh b/src/sim/init.hh index 2bbcd23da..ecc4bc347 100644 --- a/src/sim/init.hh +++ b/src/sim/init.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 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. + * * Copyright (c) 2008 The Hewlett-Packard Development Company * All rights reserved. * @@ -31,9 +43,10 @@ #ifndef __SIM_INIT_HH__ #define __SIM_INIT_HH__ -#include <Python.h> +#include "pybind11/pybind11.h" #include <list> +#include <map> #include <string> #include <inttypes.h> @@ -79,6 +92,31 @@ struct EmbeddedSwig static void initAll(); }; +class EmbeddedPyBind +{ + public: + EmbeddedPyBind(const char *_name, + void (*init_func)(pybind11::module &), + const char *_base); + + EmbeddedPyBind(const char *_name, + void (*init_func)(pybind11::module &)); + + static void initAll(); + + private: + void (*initFunc)(pybind11::module &); + + bool depsReady() const; + void init(pybind11::module &m); + + bool registered; + const std::string name; + const std::string base; + + static std::map<std::string, EmbeddedPyBind *> &getMap(); +}; + int initM5Python(); int m5Main(int argc, char **argv); PyMODINIT_FUNC initm5(void); diff --git a/src/sim/power/PowerModel.py b/src/sim/power/PowerModel.py index 9002743cd..ecb45b442 100644 --- a/src/sim/power/PowerModel.py +++ b/src/sim/power/PowerModel.py @@ -35,7 +35,7 @@ # # Authors: David Guillen Fandos -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * from m5.proxy import Parent @@ -46,12 +46,10 @@ class PowerModel(SimObject): type = 'PowerModel' cxx_header = "sim/power/power_model.hh" - @classmethod - def export_methods(cls, code): - code(''' - double getDynamicPower() const; - double getStaticPower() const; -''') + cxx_exports = [ + PyBindMethod("getDynamicPower"), + PyBindMethod("getStaticPower"), + ] # Keep a list of every model for every power state pm = VectorParam.PowerModelState([], "List of per-state power models.") diff --git a/src/sim/power/PowerModelState.py b/src/sim/power/PowerModelState.py index 1c37ab078..3089497c1 100644 --- a/src/sim/power/PowerModelState.py +++ b/src/sim/power/PowerModelState.py @@ -35,7 +35,7 @@ # # Authors: David Guillen Fandos -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * # Represents a power model for a simobj @@ -45,11 +45,10 @@ class PowerModelState(SimObject): abstract = True cxx_class = 'PowerModelState' - @classmethod - def export_methods(cls, code): - code(''' - double getDynamicPower() const; - double getStaticPower() const; -''') + cxx_exports = [ + PyBindMethod("getDynamicPower"), + PyBindMethod("getStaticPower"), + ] + diff --git a/src/sim/power/ThermalDomain.py b/src/sim/power/ThermalDomain.py index 215d0863f..7d89d1a02 100644 --- a/src/sim/power/ThermalDomain.py +++ b/src/sim/power/ThermalDomain.py @@ -35,7 +35,7 @@ # # Authors: David Guillen Fandos -from m5.SimObject import SimObject +from m5.SimObject import * from m5.params import * # Represents a group of simobj which produce heat @@ -43,11 +43,9 @@ class ThermalDomain(SimObject): type = 'ThermalDomain' cxx_header = "sim/power/thermal_domain.hh" - @classmethod - def export_methods(cls, code): - code(''' - void setNode(ThermalNode * node); -''') + cxx_exports = [ + PyBindMethod("setNode"), + ] # Static temperature which may change over time initial_temperature = Param.Float(25.0, "Initial temperature") diff --git a/src/sim/power/ThermalModel.py b/src/sim/power/ThermalModel.py index 4c397119d..e6a01b2be 100644 --- a/src/sim/power/ThermalModel.py +++ b/src/sim/power/ThermalModel.py @@ -35,7 +35,7 @@ # # Authors: David Guillen Fandos -from m5.SimObject import SimObject +from m5.SimObject import * from ClockedObject import ClockedObject from m5.params import * @@ -52,11 +52,9 @@ class ThermalResistor(SimObject): type = 'ThermalResistor' cxx_header = "sim/power/thermal_model.hh" - @classmethod - def export_methods(cls, code): - code(''' - void setNodes(ThermalNode * node1, ThermalNode * node2); -''') + cxx_exports = [ + PyBindMethod("setNodes"), + ] resistance = Param.Float(1.0, "Thermal resistance, expressed in Kelvin per Watt") @@ -65,11 +63,9 @@ class ThermalCapacitor(SimObject): type = 'ThermalCapacitor' cxx_header = "sim/power/thermal_model.hh" - @classmethod - def export_methods(cls, code): - code(''' - void setNodes(ThermalNode * node1, ThermalNode * node2); -''') + cxx_exports = [ + PyBindMethod("setNodes"), + ] capacitance = Param.Float(1.0, "Thermal capacitance, expressed in Joules per Kelvin") @@ -78,11 +74,9 @@ class ThermalReference(SimObject, object): type = 'ThermalReference' cxx_header = "sim/power/thermal_model.hh" - @classmethod - def export_methods(cls, code): - code(''' - void setNode(ThermalNode * node); -''') + cxx_exports = [ + PyBindMethod("setNode"), + ] # Static temperature which may change over time temperature = Param.Float(25.0, "Operational temperature in Celsius") @@ -93,16 +87,14 @@ class ThermalModel(ClockedObject): type = 'ThermalModel' cxx_header = "sim/power/thermal_model.hh" - @classmethod - def export_methods(cls, code): - code(''' - void addCapacitor(ThermalCapacitor *obj); - void addResistor(ThermalResistor *obj); - void addReference(ThermalReference *obj); - void addDomain(ThermalDomain *obj); - void addNode(ThermalNode *obj); - void doStep(); -''') + cxx_exports = [ + PyBindMethod("addCapacitor"), + PyBindMethod("addResistor"), + PyBindMethod("addReference"), + PyBindMethod("addDomain"), + PyBindMethod("addNode"), + PyBindMethod("doStep"), + ] step = Param.Float(0.01, "Simulation step (in seconds) for thermal simulation") diff --git a/src/unittest/SConscript b/src/unittest/SConscript index 2737be8f5..1f723ed2a 100644 --- a/src/unittest/SConscript +++ b/src/unittest/SConscript @@ -46,8 +46,7 @@ UnitTest('strnumtest', 'strnumtest.cc') UnitTest('trietest', 'trietest.cc') stattest_py = PySource('m5', 'stattestmain.py', skip_lib=True) -stattest_swig = SwigSource('_m5', 'stattest.i', skip_lib=True) -UnitTest('stattest', 'stattest.cc', stattest_py, stattest_swig, main=True) +UnitTest('stattest', 'stattest.cc', stattest_py, main=True) UnitTest('symtest', 'symtest.cc') UnitTest('tokentest', 'tokentest.cc') diff --git a/src/unittest/stattest.cc b/src/unittest/stattest.cc index 20f2fd548..e3722204b 100644 --- a/src/unittest/stattest.cc +++ b/src/unittest/stattest.cc @@ -28,6 +28,8 @@ * Authors: Nathan Binkert */ +#include "pybind11/pybind11.h" + #include <iomanip> #include <iostream> #include <string> @@ -37,8 +39,11 @@ #include "base/statistics.hh" #include "base/types.hh" #include "sim/core.hh" +#include "sim/init.hh" #include "sim/stat_control.hh" +namespace py = pybind11; + // override the default main() code for this unittest const char *m5MainCommands[] = { "import m5.stattestmain", @@ -52,8 +57,6 @@ using namespace Stats; double testfunc(); struct StatTest; StatTest & __stattest(); -void stattest_init(); -void stattest_run(); double @@ -123,18 +126,6 @@ __stattest() } void -stattest_init() -{ - __stattest().init(); -} - -void -stattest_run() -{ - __stattest().run(); -} - -void StatTest::init() { EventQueue *q = getEventQueue(0); @@ -680,3 +671,16 @@ StatTest::run() s20[1] = 1; } + +static void +stattest_init_pybind(py::module &m_internal) +{ + py::module m = m_internal.def_submodule("stattest"); + + m + .def("stattest_init", []() { __stattest().init(); }) + .def("stattest_run", []() { __stattest().run(); }) + ; +} + +static EmbeddedPyBind embed_("stattest", stattest_init_pybind); diff --git a/src/unittest/stattest.i b/src/unittest/stattest.i deleted file mode 100644 index 66990689f..000000000 --- a/src/unittest/stattest.i +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 The Hewlett-Packard Development Company - * 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. - * - * Authors: Nathan Binkert - */ - -%module(package="_m5") stattest - -%inline %{ -extern void stattest_init(); -extern void stattest_run(); -%} diff --git a/tests/configs/switcheroo.py b/tests/configs/switcheroo.py index c94dc7590..43bd5eba1 100644 --- a/tests/configs/switcheroo.py +++ b/tests/configs/switcheroo.py @@ -106,7 +106,7 @@ def run_test(root, switcher=None, freq=1000, verbose=False): # Worse yet, they include the timestamp, which makes them highly # variable and unsuitable for comparing as test outputs. if not verbose: - _m5.core.Logger.setLevel(_m5.core.Logger.WARN) + _m5.core.setLogLevel(_m5.core.LogLevel.WARN) # instantiate configuration m5.instantiate() |