ext: Fix compilation of the sst gem5 integration.
Replace the old copied version of gem5's main function with an updated
copy. This fixes compilation, but there's still a problem running an sst
example where there's a segfault inside the python interpreter.
Change-Id: I95714a9264636c14e1dda3174bc0d79e3d881727
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/54006
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/54266
diff --git a/ext/sst/gem5.cc b/ext/sst/gem5.cc
index c93c722..1d90bc5 100644
--- a/ext/sst/gem5.cc
+++ b/ext/sst/gem5.cc
@@ -89,6 +89,9 @@
#include <string>
#include <vector>
+#include <pybind11/embed.h>
+#include <pybind11/pybind11.h>
+
// gem5 Headers
#include <sim/core.hh>
#include <sim/init.hh>
@@ -118,6 +121,8 @@
// More SST Headers
#include <core/timeConverter.h>
+namespace py = pybind11;
+
gem5Component::gem5Component(SST::ComponentId_t id, SST::Params& params):
SST::Component(id), threadInitialized(false)
{
@@ -365,98 +370,26 @@
return 0;
}
-int
-gem5Component::startM5(int argc, char **_argv)
-{
- // This function should be similar to m5Main() of src/sim/init.cc
-
-#if HAVE_PROTOBUF
- // Verify that the version of the protobuf library that we linked
- // against is compatible with the version of the headers we
- // compiled against.
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-#endif
-
-
-#if PY_MAJOR_VERSION >= 3
- typedef std::unique_ptr<wchar_t[], decltype(&PyMem_RawFree)> WArgUPtr;
- std::vector<WArgUPtr> v_argv;
- std::vector<wchar_t *> vp_argv;
- v_argv.reserve(argc);
- vp_argv.reserve(argc);
- for (int i = 0; i < argc; i++) {
- v_argv.emplace_back(Py_DecodeLocale(_argv[i], NULL), &PyMem_RawFree);
- vp_argv.emplace_back(v_argv.back().get());
- }
-
- wchar_t **argv = vp_argv.data();
-#else
- char **argv = _argv;
-#endif
-
- PySys_SetArgv(argc, argv);
-
- // We have to set things up in the special __main__ module
- pythonMain = PyImport_AddModule(PyCC("__main__"));
- if (pythonMain == NULL)
- panic("Could not import __main__");
-
- const std::vector<std::string> commands = {
- "import m5",
- "m5.main()"
- };
- execPythonCommands(commands);
-
-#if HAVE_PROTOBUF
- google::protobuf::ShutdownProtobufLibrary();
-#endif
-
- return 0;
-}
-
void
gem5Component::initPython(int argc, char *_argv[])
{
- // should be similar to main() in src/sim/main.cc
- PyObject *mainModule, *mainDict;
-
- int ret;
-
- // Initialize m5 special signal handling.
+ // Initialize gem5 special signal handling.
gem5::initSignals();
-#if PY_MAJOR_VERSION >= 3
- std::unique_ptr<wchar_t[], decltype(&PyMem_RawFree)> program(
- Py_DecodeLocale(_argv[0], NULL),
- &PyMem_RawFree);
- Py_SetProgramName(program.get());
-#else
- Py_SetProgramName(_argv[0]);
-#endif
+ if (!Py_IsInitialized())
+ py::initialize_interpreter(false, argc, _argv);
- // Register native modules with Python's init system before
- // initializing the interpreter.
- if (!Py_IsInitialized()) {
- gem5::registerNativeModules();
- // initialize embedded Python interpreter
- Py_Initialize();
- } else {
- // https://stackoverflow.com/a/28349174
- PyImport_AddModule("_m5");
- PyObject* module = gem5::EmbeddedPyBind::initAll();
- PyObject* sys_modules = PyImport_GetModuleDict();
- PyDict_SetItemString(sys_modules, "_m5", module);
- Py_DECREF(module);
+ auto importer = py::module_::import("importer");
+ importer.attr("install")();
+
+ try {
+ py::module_::import("m5").attr("main")();
+ } catch (py::error_already_set &e) {
+ if (!e.matches(PyExc_SystemExit)) {
+ std::cerr << e.what();
+ output.output(CALL_INFO, "Calling m5.main(...) failed.\n");
+ }
}
-
-
- // Initialize the embedded m5 python library
- ret = gem5::EmbeddedPython::initAll();
-
- if (ret == 0)
- startM5(argc, _argv); // start m5
- else
- output.output(CALL_INFO, "Not calling m5Main due to ret=%d\n", ret);
}
void
diff --git a/ext/sst/gem5.hh b/ext/sst/gem5.hh
index 34d8bd6..2712411 100644
--- a/ext/sst/gem5.hh
+++ b/ext/sst/gem5.hh
@@ -101,8 +101,6 @@
void finish();
bool clockTick(SST::Cycle_t current_cycle);
- int startM5(int argc, char **_argv);
-
// stuff needed for gem5 sim
public: