File indexing completed on 2024-04-06 12:13:00
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, bool isFile)
0029 : theProcessPSet(), theInterpreter(true) {
0030 edm::python::initializePyBind11Module();
0031 prepareToRead();
0032 read(config, isFile);
0033 }
0034
0035 PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config, bool isFile, const std::vector<std::string>& args)
0036 : theProcessPSet(), theInterpreter(true) {
0037 edm::python::initializePyBind11Module();
0038 prepareToRead();
0039 {
0040 typedef std::unique_ptr<wchar_t[], decltype(&PyMem_RawFree)> WArgUPtr;
0041 std::vector<WArgUPtr> v_argv;
0042 std::vector<wchar_t*> vp_argv;
0043 v_argv.reserve(args.size());
0044 vp_argv.reserve(args.size());
0045 for (size_t i = 0; i < args.size(); i++) {
0046 v_argv.emplace_back(Py_DecodeLocale(args[i].c_str(), nullptr), &PyMem_RawFree);
0047 vp_argv.emplace_back(v_argv.back().get());
0048 }
0049
0050 wchar_t** argvt = vp_argv.data();
0051
0052 PySys_SetArgv(args.size(), argvt);
0053 }
0054 read(config, isFile);
0055 }
0056
0057 PyBind11ProcessDesc::~PyBind11ProcessDesc() = default;
0058
0059 void PyBind11ProcessDesc::prepareToRead() {
0060
0061 theInterpreter.mainModule = pybind11::module::import("__main__");
0062 theInterpreter.mainModule.attr("processDesc") = this;
0063 theInterpreter.mainModule.attr("processPSet") = &theProcessPSet;
0064 }
0065
0066 void PyBind11ProcessDesc::read(std::string const& config, bool isFile) {
0067 try {
0068 if (isFile)
0069 readFile(config);
0070 else
0071 readString(config);
0072 } catch (pybind11::error_already_set const& e) {
0073 edm::pythonToCppException("Configuration", e.what());
0074 }
0075 }
0076
0077 void PyBind11ProcessDesc::readFile(std::string const& fileName) {
0078 pybind11::eval_file(fileName);
0079 std::string command("process.fillProcessDesc(processPSet)");
0080 pybind11::exec(command);
0081 }
0082
0083 void PyBind11ProcessDesc::readString(std::string const& pyConfig) {
0084 std::string command = pyConfig;
0085 command += "\nprocess.fillProcessDesc(processPSet)";
0086 pybind11::exec(command.c_str());
0087 }
0088
0089 std::unique_ptr<edm::ParameterSet> PyBind11ProcessDesc::parameterSet() const {
0090 return std::make_unique<edm::ParameterSet>(theProcessPSet.pset());
0091 }
0092
0093 std::string PyBind11ProcessDesc::dump() const {
0094 std::ostringstream os;
0095 os << theProcessPSet.dump();
0096 return os.str();
0097 }
0098
0099
0100 std::unique_ptr<edm::ProcessDesc> PyBind11ProcessDesc::processDesc() const {
0101 return std::make_unique<edm::ProcessDesc>(parameterSet());
0102 }