Back to home page

Project CMSSW displayed by LXR

 
 

    


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   //  pybind11::scoped_interpreter guard{};
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     // if it ends with py, it's a file
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 // For backward compatibility only.  Remove when no longer used.
0108 std::unique_ptr<edm::ProcessDesc> PyBind11ProcessDesc::processDesc() const {
0109   return std::make_unique<edm::ProcessDesc>(parameterSet());
0110 }