Enabling the Python bindings
DUNE has a set of Python bindings that allow to access a lot of its features from Python.
When building from source
To enable the Python bindings for a Dune installation that you build from source, first do build Dune from the source following the instructions. Starting with DUNE 2.9 the support for the Python bindings is then built by default.
Do not forget that you need to build DUNE into shared libraries if you want
to use the Python bindings, because otherwise obscure crashes can happen.
This is particularly true if you plan on using the UGGrid
grid implementation.
To enable building shared libraries please add -DBUILD_SHARED_LIBS=ON
to your CMake options.
The internal virtual environment
When built from source, the DUNE build system will set up an internal virtual environment.
This provides an easy way to use the Python bindings of DUNE.
(For this to work you have to have the Python virtual environment capabilities installed.
For example, on a Debian system you need the python3-venv
package.)
The virtual environment is called dune-env
, and it appears in the build directory
of dune-common
. To run a Python program in this environment call
path/to/dune-common/build-cmake/run-in-dune-env python3 [...]
To enable it permanently, call
source path/to/dune-common/build-cmake/dune-env/bin/activate
After this, starting any Python program from the same shell will use the
dune-env
virtual environment.
Alternatively, a custom virtual environment can be activated before configuring DUNE that will replace the internal virtual environment.
Running a first program
To test the Pything bindings take a small example program, like
from dune.common import FieldVector
print("START")
x=FieldVector([1,2])
print("END")
This first example only needs dune-common
module. Copy it into a file
dune-common-test.py
, and start it with python3 dune-common-test.py
.
The output should be
START
DUNE-INFO: Generating dune-py module in /dune/dune-common/build-cmake/dune-env/.cache/dune-py
DUNE-INFO: Compiling FieldVector (new)
END
Running the program will be slow the first time, because some additional C++ code is built and linked. Starting the program a second time will not do that again, and the program will run much faster.
If you have dune-grid
installed you can also check
from dune.grid import structuredGrid
grid = structuredGrid([0,0],[1,1],[10,10])
print( grid.size(0) ) # should return 100
How it works: Just-in-time compilation
You will have noticed that DUNE Python programs will be slow on first start,
with messages saying DUNE-INFO: Compiling [...]
. These compilations happen
because DUNE uses so many C++ templates. There are so many combinations of
template parameters that they cannot all be compiled beforehand. Instead,
when you run your Python code the program determines precisely what template
instantiations are needed, and compiles them on-the-fly. This is called
Just-in-time compilation (JIT). The outcome of these compilations are cached
and reused when you start your program a second time. Therefore, the
run-time overhead caused by having to compile additional C++ from within
Python happens only once.
The dune-py
module
The just-in-time (JIT) compilation happens in a dedicated DUNE module called dune-py
.
This module is automatically set up the first time a DUNE package is imported in Python.
By default, the dune-py
module is created in a folder .cache
in the current Python virtual environment. In other words, by default it appears in dune-common/build-cmake/dune-env/.cache/dune-py
.
The location of the module can be changed by setting the environment variable DUNE_PY_DIR
.
It is possible to set the directory for a single runs of a program. For example,
DUNE_PY_DIR="." ./my-python-test.py
will create the dune-py
module in the current directory.
This can be useful to make sure that all JIT-compiled modules get rebuilt.