Skip to content

Commit

Permalink
Merge pull request #4029 from lisajulia/fix/pyAction-build-only-one-s…
Browse files Browse the repository at this point in the history
…hared-library

Fix/py action build only one shared library
  • Loading branch information
blattms committed Apr 30, 2024
2 parents 2a34fc4 + 2b017ba commit 6af6865
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 100 deletions.
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()));
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 {


/*
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
```
```

0 comments on commit 6af6865

Please sign in to comment.