monoprop

Building from Source

Build the Python bindings and the C++ unit-test tree, with or without MPI.

monoprop has one supported from-source build workflow:

  • the Python bindings — the nanobind extension behind import monoprop, built with scikit-build-core and driven by uv (or pip);
  • the C++ unit tests — built within the same uv (or pip) invocation.

MPI is off by default in every build path; you enable it explicitly. The mechanism differs by build:

BuildEnable MPI with
Python bindings and C++ tests (scikit-build / uv / pip)--config-settings=cmake.define.monoprop_ENABLE_MPI=ON (or export SKBUILD_CMAKE_ARGS="-Dmonoprop_ENABLE_MPI=ON")

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 uv package manager (for the bindings)
  • an MPI implementation such as Open MPI (only for MPI builds)
  • hwloc (version 2.9+) and pkg-config (required so CMake can locate hwloc)

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 with Nix

The repository is also a Nix flake:

CommandWhat it gives you
nix developa shell with every prerequisite above, plus uv, just and Node.js
nix build .#monopropthe Python package, built without MPI
nix build .#monoprop-mpithe same package with monoprop_ENABLE_MPI=ON
nix runa Python interpreter with monoprop importable

Inside nix develop the uv sync and just workflows below apply unchanged. The shell sets two variables that only matter on NixOS: UV_PYTHON_PREFERENCE=only-system, because uv's managed interpreters expect a loader NixOS does not provide, and LD_LIBRARY_PATH, so that manylinux wheels can resolve libstdc++.

The packaged build deviates from the uv build in three places, all in nix/monoprop.nix:

  • the C++ unit tests are disabled, because they resolve msgpack-cxx through a git fetch that the build sandbox denies — build them from the dev shell instead;
  • monoprop_ENABLE_ARCH_FLAGS is off, since a store path may be substituted onto a machine other than the one that built it; pass .override { enableArchFlags = true; } for a native build;
  • the version is pinned, because setuptools-scm cannot read git metadata inside the sandbox; bump it alongside the release tag.

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 -v

This 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=ON

The same override works with pip when installing from a checkout:

pip install . --config-settings=cmake.define.monoprop_ENABLE_MPI=ON

Verify 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.py

For 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.py

See Parallelism and distribution for the communicator options and the operator-partitioning controls.

Building the C++ unit tests

The supported C++ workflow reuses the build tree produced by uv sync. Do not run cmake --preset ... to configure this project directly: the top-level CMake configuration expects scikit-build-core to provide Python, nanobind, and related cache variables. Instead, first create the tree with uv sync, then invoke ctest directly to run the C++ unit tests.

Release tree

uv sync --all-extras -v
ctest --test-dir build/editable/Release

This uses the scikit-build-core Release tree at build/editable/Release and runs bin/monoprop_unit_tests.x there.

Debug tree

uv sync --all-extras -v --config-settings=cmake.build-type=Debug
ctest --test-dir build/editable/Debug
  • Use just test-wide for the 64-bit monoprop_WIDE_TERM_INDEX configuration.
  • Use just code-coverage for the coverage build.
  • Use ctest --test-dir build/editable/Release -L serial or -L mpi-2 to filter the discovered C++ test set.

See also

On this page