Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/py action build only one shared library #4029

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 18 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ if (ENABLE_MOCKSIM AND ENABLE_ECL_INPUT)
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests
CONDITION ${HAVE_ECL_INPUT})
endforeach()
set_tests_properties(msim_ACTIONX PROPERTIES
ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/python:$ENV{PYTHONPATH}")
endif()
endif()

Expand Down Expand Up @@ -371,6 +373,10 @@ if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
get_filename_component(tgt ${src} NAME_WE)
target_link_libraries(${tgt} dunecommon)
endforeach()
foreach(test ACTIONX EmbeddedPython PYACTION)
set_tests_properties(${test} PROPERTIES
ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/python:$ENV{PYTHONPATH}")
endforeach()
endif()
if(BUILD_EXAMPLES)
target_link_libraries(co2brinepvt dunecommon)
Expand Down Expand Up @@ -425,7 +431,7 @@ if (OPM_ENABLE_PYTHON)
# setup.py install manually - optionally with the generated script
# setup-install.sh - and completely bypass cmake in the installation phase.
# If OPM_ENABLE_EMBEDDED_PYTHON is enabled, we also install opmcommon_python,
# to make it available in a Python console.
# to make it available in a Python console and for e.g. opm-simulators.
if (OPM_INSTALL_PYTHON OR OPM_ENABLE_EMBEDDED_PYTHON)
include(PyInstallPrefix)
install(TARGETS opmcommon_python DESTINATION ${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX}/opm)
Expand All @@ -436,11 +442,18 @@ if (OPM_ENABLE_PYTHON)
python/install.py
${PROJECT_BINARY_DIR}/python/opm
${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} 1)")

## Need to install this Python script such that it can be used by opm-simulators when building against an installed
## opm-common
install( PROGRAMS "python/install.py" DESTINATION "${OPM_PYTHON_COMMON_DIR}" )
endif()
if (OPM_ENABLE_EMBEDDED_PYTHON)
install(
CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE}
python/install.py
${PROJECT_BINARY_DIR}/python/opm_embedded
${DEST_PREFIX}${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} 1)")
endif()
## Need to install this Python script such that it can be used by opm-simulators when building against an installed
## opm-common
install( PROGRAMS "python/install.py" DESTINATION "${OPM_PYTHON_COMMON_DIR}" )
endif()

# Observe that if the opmcommon library has been built as a shared library the
Expand Down
69 changes: 0 additions & 69 deletions opm/input/eclipse/Python/EmbedModule.hpp

This file was deleted.

4 changes: 2 additions & 2 deletions opm/input/eclipse/Python/PyRunModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ PyRunModule::PyRunModule(std::shared_ptr<const Python> python, const std::string
try {
this->opm_embedded = py::module::import("opm_embedded");
} catch (const std::exception& e) {
OpmLog::error(fmt::format("Exception thrown when loading Python module opm_embedded: {}"), e.what());
OpmLog::error(fmt::format("Exception thrown when loading Python module opm_embedded: {}. Possibly the PYTHONPATH of the system is not set correctly.", e.what()));
blattms marked this conversation as resolved.
Show resolved Hide resolved
throw e;
} catch (...) {
OPM_THROW(std::runtime_error, "General exception thrown when loading Python module opm_embedded!");
OPM_THROW(std::runtime_error, "General exception thrown when loading Python module opm_embedded, possibly the PYTHONPATH of the system is not set correctly.");
}
}

Expand Down
74 changes: 57 additions & 17 deletions opm/input/eclipse/Python/PythonInterp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,32 @@
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <pybind11/pytypes.h>
#include <fmt/format.h>

#include <opm/common/ErrorMacros.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>

#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/common/utility/FileSystem.hpp>

#include "python/cxx/export.hpp"
#include "PythonInterp.hpp"
#include "EmbedModule.hpp"

namespace py = pybind11;
namespace Opm {


lisajulia marked this conversation as resolved.
Show resolved Hide resolved
/*
OPM_EMBEDDED_MODULE create a Python of all the Python/C++ classes which are
generated in the python::common::export_all_opm_embedded() function in the wrapping code.
The same module is created as a Pybind 11 module in export.cpp
*/

OPM_EMBEDDED_MODULE(opm_embedded, module) {
python::common::export_all(module);
}


/**
* @brief Executes Python code within a specified context.
*
* This function executes the provided Python code within the given context.
*
* @param python_code The Python code to execute, provided as a string.
* @param context The Python module providing the context for execution.
*
* @return bool The return value set at the "result" attribute in the context module.
*
*/
bool PythonInterp::exec(const std::string& python_code, py::module& context) {
py::bool_ def_result = false;
context.attr("result") = &def_result;
Expand All @@ -55,24 +57,62 @@ bool PythonInterp::exec(const std::string& python_code, py::module& context) {
}



/**
* @brief Executes Python code within a specified context.
*
* This function imports the module "opm_embedded" (initialized at opm-common/python/opm_embeded/__init__.py)
* as the context module, adds the parser and deck to the context and executes the given Python code.
*
* @param python_code The Python code to execute, provided as a string.
* @param parser The parser.
* @param deck The current deck.
*
* @return bool The return value set at the "result" attribute in the context module.
*
*/
bool PythonInterp::exec(const std::string& python_code, const Parser& parser, Deck& deck) {
if (!this->guard)
throw std::logic_error("Python interpreter not enabled");

auto context = py::module::import("opm_embedded");
py::module context;
try {
context = py::module::import("opm_embedded");
} catch (const std::exception& e) {
OpmLog::error(fmt::format("Exception thrown when loading Python module opm_embedded: {}", e.what()));
throw e;
} catch (...) {
OPM_THROW(std::runtime_error, "General exception thrown when loading Python module opm_embedded!");
}
context.attr("deck") = &deck;
context.attr("parser") = &parser;
return this->exec(python_code, context);
}



/**
* @brief Executes Python code within a specified context.
*
* This function imports the module "opm_embedded" (initialized at opm-common/python/opm_embeded/__init__.py)
* as the context module and executes the given Python code.
*
* @param python_code The Python code to execute, provided as a string.
*
* @return bool The return value set at the "result" attribute in the context module.
*
*/
bool PythonInterp::exec(const std::string& python_code) {
if (!this->guard)
throw std::logic_error("Python interpreter not enabled");

auto context = py::module::import("opm_embedded");
py::module context;
try {
context = py::module::import("opm_embedded");
} catch (const std::exception& e) {
OpmLog::error(fmt::format("Exception thrown when loading Python module opm_embedded: {}", e.what()));
throw e;
} catch (...) {
OPM_THROW(std::runtime_error, "General exception thrown when loading Python module opm_embedded!");
}
return this->exec(python_code, context);
}

Expand Down
22 changes: 15 additions & 7 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@ This folder contains the Python bindings and code required for embedding python

For the Python bindings, see the [Python bindings of opm-simulators](https://github.com/OPM/opm-simulators/blob/master/python/README.md).

For embedding python, see the [documentation](https://opm-project.org/?page_id=1454).
For embedded python code, see the [documentation](https://opm-project.org/?page_id=1454).

To enable tooltips for opm_embedded on VSCode (embedded python code):
- Install opm-common
- Copy the file "<opm-common-folder>/python/opm_embedded/__init__.pyi" into the folder at "python.analysis.stubPath" of VS Code and rename it to "opm_embedded.pyi"
You can recreate this stub file by executing "stubgen -m opmcommon_python" in "<opm-common-build-folder>/python/opm", renaming the resuling stub file from "opmcommon_python.pyi" to "opm_embedded.pyi" and adding the lines
```python
To enable tooltips for embedded python code (opm_embedded) for the editor VS Code:
- Either: Install opm-common.
- Or: Copy the file `<opm-common-folder>/python/opm_embedded/__init__.pyi` into the folder defined in variable `python.analysis.stubPath` of VS Code and rename it to `opm_embedded.pyi`.

You can recreate this stub file by executing
```
stubgen -m opmcommon_python -o . && cat opmcommon_python.pyi | sed "s/class Builtin:/current_ecl_state: EclipseState\ncurrent_report_step: int\ncurrent_schedule: Schedule\ncurrent_summary_state:\n\nclass Builtin:/" > opm_embedded.pyi
```
in `<opm-common-build-folder>/python/opm`.

This will copy the resulting stub file `opmcommon_python.pyi` to "opm_embedded.pyi" and add the lines
```python
current_ecl_state: EclipseState
current_report_step: int
current_schedule: Schedule
current_summary_state: SummaryState
```
```