File indexing completed on 2023-03-17 11:03:34
0001 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0002 #include "FWCore/ParameterSet/interface/ProcessDesc.h"
0003 #include "FWCore/PythonParameterSet/interface/PyBind11ProcessDesc.h"
0004 #include "FWCore/PythonParameterSet/src/initializePyBind11Module.h"
0005 #include "FWCore/PythonParameterSet/interface/PyBind11Wrapper.h"
0006 #include <pybind11/embed.h>
0007 #include <pybind11/pybind11.h>
0008
0009 #include <sstream>
0010 #include <iostream>
0011
0012 PyBind11InterpreterSentry::PyBind11InterpreterSentry(bool ownsInterpreter)
0013 : mainModule(), ownsInterpreter_(ownsInterpreter) {
0014 if (ownsInterpreter_) {
0015 pybind11::initialize_interpreter();
0016 }
0017 }
0018
0019 PyBind11InterpreterSentry::~PyBind11InterpreterSentry() {
0020 if (ownsInterpreter_) {
0021 mainModule = pybind11::object();
0022 pybind11::finalize_interpreter();
0023 }
0024 }
0025
0026 PyBind11ProcessDesc::PyBind11ProcessDesc() : theProcessPSet(), theInterpreter(false) {}
0027
0028 PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config) : theProcessPSet(), theInterpreter(true) {
0029 edm::python::initializePyBind11Module();
0030 prepareToRead();
0031 read(config);
0032 }
0033
0034 PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config, int argc, char* argv[])
0035 : theProcessPSet(),
0036 theInterpreter(true)
0037
0038 {
0039 edm::python::initializePyBind11Module();
0040 prepareToRead();
0041 {
0042 #if PY_MAJOR_VERSION >= 3
0043 typedef std::unique_ptr<wchar_t[], decltype(&PyMem_RawFree)> WArgUPtr;
0044 std::vector<WArgUPtr> v_argv;
0045 std::vector<wchar_t*> vp_argv;
0046 v_argv.reserve(argc);
0047 vp_argv.reserve(argc);
0048 for (int i = 0; i < argc; i++) {
0049 v_argv.emplace_back(Py_DecodeLocale(argv[i], nullptr), &PyMem_RawFree);
0050 vp_argv.emplace_back(v_argv.back().get());
0051 }
0052
0053 wchar_t** argvt = vp_argv.data();
0054 #else
0055 char** argvt = argv;
0056 #endif
0057
0058 PySys_SetArgv(argc, argvt);
0059 }
0060 read(config);
0061 }
0062
0063 PyBind11ProcessDesc::~PyBind11ProcessDesc() = default;
0064
0065 void PyBind11ProcessDesc::prepareToRead() {
0066
0067 theInterpreter.mainModule = pybind11::module::import("__main__");
0068 theInterpreter.mainModule.attr("processDesc") = this;
0069 theInterpreter.mainModule.attr("processPSet") = &theProcessPSet;
0070 }
0071
0072 void PyBind11ProcessDesc::read(std::string const& config) {
0073 try {
0074
0075 if (config.substr(config.size() - 3) == ".py") {
0076 readFile(config);
0077 } else {
0078 readString(config);
0079 }
0080 } catch (pybind11::error_already_set const& e) {
0081 edm::pythonToCppException("Configuration", e.what());
0082 }
0083 }
0084
0085 void PyBind11ProcessDesc::readFile(std::string const& fileName) {
0086 pybind11::eval_file(fileName);
0087 std::string command("process.fillProcessDesc(processPSet)");
0088 pybind11::exec(command);
0089 }
0090
0091 void PyBind11ProcessDesc::readString(std::string const& pyConfig) {
0092 std::string command = pyConfig;
0093 command += "\nprocess.fillProcessDesc(processPSet)";
0094 pybind11::exec(command.c_str());
0095 }
0096
0097 std::unique_ptr<edm::ParameterSet> PyBind11ProcessDesc::parameterSet() const {
0098 return std::make_unique<edm::ParameterSet>(theProcessPSet.pset());
0099 }
0100
0101 std::string PyBind11ProcessDesc::dump() const {
0102 std::ostringstream os;
0103 os << theProcessPSet.dump();
0104 return os.str();
0105 }
0106
0107
0108 std::unique_ptr<edm::ProcessDesc> PyBind11ProcessDesc::processDesc() const {
0109 return std::make_unique<edm::ProcessDesc>(parameterSet());
0110 }