Building from Source
Build the Python bindings and the C++ library and executables, with or without MPI.
monoprop has two build products, each with its own build system:
- the Python bindings — the nanobind extension behind
import monoprop, built with scikit-build-core and driven byuv(orpip); - the standalone C++ library and executables — built directly with CMake presets.
MPI is off by default in every build path; you enable it explicitly. The mechanism differs by build:
| Build | Enable MPI with |
|---|---|
Python bindings (scikit-build / uv / pip) | --config-settings=cmake.define.monoprop_ENABLE_MPI=ON (or export SKBUILD_CMAKE_ARGS="-Dmonoprop_ENABLE_MPI=ON") |
| C++ (CMake presets) | use the *-mpi preset |
The prebuilt wheels published to PyPI (pip install monoprop) are also built
without MPI, so a from-source build is required for multi-rank runs.
Prerequisites
- a C++23-compliant compiler; on Linux the minimum supported versions are GCC 14 and Clang 18
- CMake and Ninja
- Python 3.11 or newer and the
uvpackage manager (for the bindings) - an MPI implementation such as Open MPI (only for MPI builds)
The repository ships a DevContainer with all of the above pre-configured; opening the folder in VS Code and rebuilding the container is the quickest route to a working environment.
Building the Python bindings
uv creates a virtual environment, installs the Python dependencies, and
compiles the nanobind extension in editable mode. Re-run the sync command whenever
the dependency graph or the C++ sources change.
Without MPI (default)
uv sync --all-extras -vThis produces a single-process build with no MPI dependency.
With MPI
Pass a config-settings override to enable MPI:
uv sync --all-extras -v \
--config-settings=cmake.define.monoprop_ENABLE_MPI=ONThe same override works with pip when installing from a checkout:
pip install . --config-settings=cmake.define.monoprop_ENABLE_MPI=ONVerify the install
uv run python -c "import monoprop as mp; print(mp.__version__)"Running the bindings
A serial run is just a normal Python invocation:
uv run python your_script.pyFor a multi-rank run, launch the same script under mpiexec (requires an MPI
build) and pass comm=MPI.COMM_WORLD to the simulator:
mpiexec -n 8 uv run python your_script.pySee Parallelism and distribution for the communicator options and the operator-partitioning controls.
Building the C++ library and executables
The standalone build uses CMake presets (Ninja generator). It produces the
monoprop library plus the test executable under build/<preset>/bin/.
Default preset (no MPI)
cmake --preset release-gcc
cmake --build --preset release-gccMPI preset
Use the -mpi preset, which sets monoprop_ENABLE_MPI=ON:
cmake --preset release-gcc-mpi
cmake --build --preset release-gcc-mpiOther presets
| Preset | What it changes |
|---|---|
release-clang | Same as release-gcc, built with clang++. |
release-gcc-wide | Sets monoprop_WIDE_TERM_INDEX=ON (64-bit term indices, for more than 2^32 terms per partition). |
debug-gcc / debug-gcc-mpi | Debug builds, without and with MPI. |
coverage-gcc | Coverage build type, for gcovr (see just coverage-cpp). |
Every preset writes to build/<preset>/ and has a matching build and test
preset of the same name. These presets are the single source of truth for the
project's build configurations: CI configures through them too, so a
locally-reproduced preset build matches what CI ran.
To build a single target, pass --target:
cmake --build --preset release-gcc --target monoprop_unit_tests.xSee also
- Getting Started — installing a prebuilt release from PyPI.
- Parallelism and distribution — running across MPI ranks and shared-memory threads.
- How to Contribute — the full test and documentation workflow.