Add basic manager class fro Python interpreter

This commit is contained in:
Joakim Hove
2019-09-02 18:27:22 +02:00
parent 1c6e5f5099
commit ab2ea1acf3
7 changed files with 284 additions and 4 deletions

View File

@@ -9,6 +9,8 @@ option(ENABLE_ECL_INPUT "Enable eclipse input support?" ON)
option(ENABLE_ECL_OUTPUT "Enable eclipse output support?" ON)
option(ENABLE_MOCKSIM "Build the mock simulator for io testing" ON)
option(OPM_ENABLE_PYTHON "Enable python bindings?" OFF)
option(OPM_ENABLE_EMBEDDED_PYTHON "Enable python bindings?" OFF)
# Output implies input
if(ENABLE_ECL_OUTPUT)
@@ -211,7 +213,8 @@ install(DIRECTORY cmake DESTINATION share/opm)
install(FILES etc/opm_bash_completion.sh.in DESTINATION share/opm/etc)
if (OPM_ENABLE_PYTHON)
# -------------------------------------------------------------------------
# 1: Wrap C++ functionality in Python
find_package(PythonInterp REQUIRED)
include(FindPythonInterp)
@@ -272,6 +275,9 @@ if (OPM_ENABLE_PYTHON)
set_target_properties(opmcommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/python/python)
# -------------------------------------------------------------------------
# Let cmake configure some small shell scripts which can be used to simplify
# building and testing of the Python extensions.
configure_file(python/setup-build.sh.in tmp/setup-build.sh)
file( COPY ${PROJECT_BINARY_DIR}/tmp/setup-build.sh
DESTINATION ${PROJECT_BINARY_DIR}
@@ -283,6 +289,15 @@ if (OPM_ENABLE_PYTHON)
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
configure_file(python/enable-python.sh.in enable-python.sh)
# -------------------------------------------------------------------------
# 2: Embed the Python interpreter for keywords like PYACTION and PYINPUT
if (OPM_ENABLE_EMBEDDED_PYTHON)
add_subdirectory(python/pybind11)
#target_link_libraries(opmcommon PRIVATE pybind11::embed)
include_directories("python/pybind11/include;${PYTHON_INCLUDE_DIRS}")
target_link_libraries(opmcommon PRIVATE ${PYTHON_LIBRARY})
add_definitions(-DEMBEDDED_PYTHON)
endif()
endif()

View File

@@ -46,6 +46,8 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/Deck/DeckOutput.cpp
src/opm/parser/eclipse/Deck/Section.cpp
src/opm/parser/eclipse/Deck/UDAValue.cpp
src/opm/parser/eclipse/Python/Python.cpp
src/opm/parser/eclipse/Python/PythonInterp.cpp
src/opm/parser/eclipse/EclipseState/AquiferCT.cpp
src/opm/parser/eclipse/EclipseState/Aquifetp.cpp
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
@@ -234,6 +236,7 @@ if(ENABLE_ECL_INPUT)
tests/parser/DynamicVectorTests.cpp
tests/parser/Eclipse3DPropertiesTests.cpp
tests/parser/EclipseGridTests.cpp
tests/parser/EmbeddedPython.cpp
tests/parser/EqualRegTests.cpp
tests/parser/EventTests.cpp
tests/parser/FaceDirTests.cpp
@@ -591,7 +594,8 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/Deck/DeckOutput.hpp
opm/parser/eclipse/Deck/DeckKeyword.hpp
opm/parser/eclipse/Deck/DeckRecord.hpp
opm/parser/eclipse/Deck/UDAValue.hpp)
opm/parser/eclipse/Deck/UDAValue.hpp
opm/parser/eclipse/Python/Python.hpp)
endif()
if(ENABLE_ECL_OUTPUT)
list(APPEND PUBLIC_HEADER_FILES

View File

@@ -0,0 +1,65 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_EMBEDDED_PYTHON
#define OPM_EMBEDDED_PYTHON
#include <memory>
#include <string>
namespace Opm {
class PythonInterp;
/*
This class is a thin wrapper around the PythonInterp class. The Python class
can always be safely instantiated, but the actual PythonInterp implementation
depends on whether Python support was enabled when this library instance was
compiled.
If one the methods actually invoking the Python interpreter is invoked without
proper Python support a dummy PythinInterp instance will be used; and that
will just throw std::logic_error. The operator bool can be used to check if
this Python manager indeed has a valid Python runtime:
Python python;
if (python)
python.exec("print('Hello world')")
else
OpmLog::Error("This version of opmcommon has been built with support for embedded Python");
*/
class Python {
public:
Python();
bool exec(const std::string& python_code);
explicit operator bool() const;
private:
std::shared_ptr<PythonInterp> interp;
};
}
#endif

View File

@@ -0,0 +1,45 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/parser/eclipse/Python/Python.hpp>
#include "PythonInterp.hpp"
namespace Opm {
Python::Python():
interp(std::make_shared<PythonInterp>())
{
}
bool Python::exec(const std::string& python_code) {
this->interp->exec(python_code);
return true;
}
Python::operator bool() const {
if (this->interp)
return bool( *this->interp );
else
return false;
}
}

View File

@@ -0,0 +1,38 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "PythonInterp.hpp"
#ifdef EMBEDDED_PYTHON
#include <pybind11/embed.h>
namespace py = pybind11;
namespace Opm {
bool PythonInterp::exec(const std::string& python_code) {
py::object scope = py::module::import("__main__").attr("__dict__");
py::exec(python_code, scope);
return true;
}
}
#endif

View File

@@ -0,0 +1,66 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EMBEDDED_PYTHON_INTERP
#define EMBEDDED_PYTHON_INTERP
#include <string>
#include <stdexcept>
#ifdef EMBEDDED_PYTHON
#include <pybind11/embed.h>
namespace py = pybind11;
#endif
namespace Opm {
#ifdef EMBEDDED_PYTHON
class PythonInterp {
public:
bool exec(const std::string& python_code);
explicit operator bool() const { return true; }
private:
py::scoped_interpreter guard = {};
};
#else
class PythonInterp {
public:
bool exec(const std::string&) {
return this->fail();
};
explicit operator bool() const { return false; }
private:
bool fail() { throw std::logic_error("The current opm code has been built without Python support;"); }
};
#endif
}
#endif

View File

@@ -0,0 +1,47 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#include <memory>
#define BOOST_TEST_MODULE EMBEDDED_PYTHON
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Python/Python.hpp>
#ifndef EMBEDDED_PYTHON
BOOST_AUTO_TEST_CASE(INSTANTIATE) {
Opm::Python python;
BOOST_CHECK(!python);
BOOST_CHECK_THROW(python.exec("print('Hello world')"), std::logic_error);
}
#else
BOOST_AUTO_TEST_CASE(INSTANTIATE) {
Opm::Python python;
BOOST_CHECK(python);
BOOST_CHECK_NO_THROW(python.exec("print('Hello world')"));
}
#endif