Compiling and Installing SLUG
Compilation is only necessary if you are installing SLUG from source, as described in Getting SLUG. If you are installing from PyPI or a container, you can skip this section.
There are two ways to build a source checkout. The first, described in
Configuring and Building below, is to build it in place with CMake. This has no
separate installation step: it produces the slug command-line executable
directly in the build directory, and the compiled Python extension module lands
directly inside the slugpy package in the source tree, alongside its
pure-Python code. This is the most flexible option, and the one to use if you
plan to modify SLUG. The second, described in Installing a Source Checkout with pip
below, is to build and install it into a Python environment with pip, exactly
as a PyPI installation would, but compiled on your own system.
Dependencies
Required
CMake, version 3.15 or later.
A C++23-capable compiler. The following compilers are known to work:
GCC 13 or later
Clang 17 or later (paired with a libc++ of the same version or newer)
Intel’s LLVM-based
icpx/oneAPI 2024.2.0+ (requires the flag-fp-model=strictfor correct behavior)Other C++23-capable compilers have not been tested.
The GNU Scientific Library (GSL).
HDF5 (only its C library is needed; HDF5’s optional C++ component is not required).
Bundled (no action needed)
These are vendored as git submodules under src/extern and built
automatically as part of the normal build – just make sure they were
fetched (see Getting SLUG on cloning with submodules; if you forgot,
git submodule update --init --recursive from the repository root
fetches them after the fact too):
pybind11, used to build the Python bindings (see below).
A reference implementation of C++23’s
<mdspan>(from the Kokkos mdspan project), used as a last resort if neither the compiler’s own standard library nor an externally installedmdspanpackage provides one.Whether a given compiler provides
<mdspan>natively depends on the exact standard-library snapshot it was built against, not just its nominal major version – e.g. Homebrew’s owngcc@16build on macOS bundles a libstdc++ new enough to have it, while thegcc-16package from Ubuntu’sppa:ubuntu-toolchain-r/test(as used in CI) does not, as of when this was last checked, and Apple’s own system Clang/libc++ has no native<mdspan>at all. None of this matters in practice:cmake/Mdspan.cmakedetects native support with a real compile check (not a version guess) and falls back automatically, in the order listed above, to an externally-installedmdspanpackage and then this bundled submodule – see that file’s own comments, or AGENTS.md, for the full detail. Application code always just does#include <mdspan>regardless of which provider actually supplied it.One further wrinkle specific to this bundled fallback: its own
config.hppdeliberately disables its multi-indexoperator[]on Clang versions before 17, as a workaround for a documented upstream Clang bug with parameter packs in bracket operators – so a build that falls back to this submodule under Clang 16 or earlier fails with “no viable overloaded operator[]” errors on everymdspanindexing expression, even though Clang itself supports the multidimensionaloperator[]language feature from an earlier version (see Dependencies above). This is why Clang’s own effective minimum version is 17, one version above where the language feature itself first appears.
Optional
OpenMP, for multi-threaded execution. If no OpenMP implementation is found, the build falls back to a single-threaded binary automatically, with a warning at configure time.
An MPI implementation (e.g. OpenMPI or MPICH), for multi-process execution across more than one machine – see Running SLUG With MPI. If none is found, the build falls back to a single-process binary automatically, with a warning at configure time, the same way OpenMP does above; the two are independent of each other, so a build can have either, both, or neither. MPI support only applies to the
slugcommand-line executable itself, not the Python bindings.Ninja, as the CMake generator. Not required – CMake falls back to its own platform default (Unix Makefiles on Linux/macOS) – but Ninja parallelizes the build automatically and matches what SLUG’s own CI uses, so local builds behave the same way and incremental rebuilds are noticeably faster.
Doxygen (install separately, e.g. via your system package manager or Homebrew), plus the Python packages Sphinx, Breathe, and Exhale:
pip install sphinx breathe exhale sphinx_rtd_theme
to build this documentation site itself as part of the normal build – see Building this Documentation below. Entirely optional: every other part of the build is unaffected if these aren’t installed.
Python
SLUG’s Python frontend, slugpy (see slugpy), requires Python
3.12 or later, plus astropy, h5py, NumPy, platformdirs, SciPy,
tomlkit, tqdm, and urllib3:
pip install astropy h5py numpy platformdirs scipy tomlkit tqdm urllib3
CMake builds the compiled _slug extension module against whichever
Python interpreter it finds (or the one given explicitly via
-DPython_EXECUTABLE, see below), and that same interpreter needs the
packages above installed for import slugpy to work afterwards.
pyproject.toml lists these same packages (and the optional ones just
below) under [project.dependencies]/[project.optional-dependencies].
If you instead install a source checkout with pip (see
Installing a Source Checkout with pip), pip installs them automatically.
A further three tools are needed only for specific development tasks, not
for using slugpy itself: pytest to run the
test suite, pyright to type-check
slugpy locally, and ruff to lint it:
pip install pytest pyright ruff
Configuring and Building
SLUG uses an out-of-source CMake build. From the repository root:
cmake -S . -B build -G Ninja cmake --build build
(omit -G Ninja to use CMake’s own default generator instead, if Ninja
isn’t installed – see Dependencies above). This produces the
slug command-line executable at build/slug, and builds the compiled
Python extension module directly into the slugpy package in the source
tree (so import slugpy works from the repository root immediately
afterward, with no separate install step).
A few configure-time options worth knowing about:
-DPython_EXECUTABLE=/path/to/python3Build the Python bindings against a specific Python interpreter, rather than whichever one CMake finds automatically. Needed if you use a virtual environment, conda environment, or other non-default interpreter for
slugpy– see Dependencies above for what that interpreter needs installed.-DSLUG_MDSPAN_PROVIDER=AUTO|NATIVE|PACKAGE|SUBMODULEOverride the automatic
<mdspan>provider selection described above – e.g. to require a specific provider and get a hard error if it isn’t available, rather than a silent fallback. Defaults toAUTO.-DCMAKE_BUILD_TYPE=Debug|Release|RelWithDebInfoThe usual CMake build-type switch. If it is not given, SLUG defaults to
Release, an optimized build with assertions disabled; useDebugto turn on SLUG’s internal assertion checks, e.g. when developing or debugging the code. Some of SLUG’s own performance- sensitive targets (e.g. the Python extension module) are always built with optimizations enabled regardless of this setting, since they drive the same interpolation-heavy code any analysis usingslugpydepends on.
Setting the Data Path
Once SLUG is built, it is recommended but not required to set the environment
variable SLUG_DIR to the repository root directory. This simplifies finding
the data files that SLUG needs to run by providing an automatic search path that
will be used when parsing the inputs – see The SLUG Input Deck for details. For
example, if you cloned the repository into /home/user/slug3, you can do:
export SLUG_DIR=/home/user/slug3
This step is not necessary if you installed SLUG from PyPI or a container, or if you have built and installed with pip, since those installation methods automatically set up the data path for you.
Verifying the Build
Once the build finishes, ctest (run from the build directory) executes
SLUG’s own test suite:
cd build
ctest -L quick
The quick label selects tests that run in a few seconds each and need
no large data files beyond what’s already committed to the repository;
some further, slower end-to-end tests exist but require data files too
large to distribute this way (see Tests for the full detail).
Installing a Source Checkout with pip
Instead of building in place, you can build and install a source checkout into the active Python environment by running, from the repository root:
pip install .
This uses the same CMake build, driven by
scikit-build-core, to compile
SLUG, and then installs the slugpy package, the slug command-line
executable, and the small data files distributed with the source code into the
environment, exactly as installing from PyPI does (see Getting SLUG); the
Python dependencies listed above are installed automatically. You still need a
C++ compiler, CMake, GSL, and HDF5, as described in Dependencies. As
with a PyPI installation, the large data files are not installed this way;
download them with python -m slugpy.download_data, or point the
SLUG_DIR environment variable at an existing copy of them (e.g., the
repository root of a checkout into which you have already downloaded them).
The installed slug executable is built without MPI support by default, so
that it does not depend on any particular MPI library. To build it with MPI
support, pass the corresponding CMake option through pip:
CMAKE_ARGS="-DSLUG_ENABLE_MPI=ON" pip install .
Other CMake options described above can be passed the same way.
Building this Documentation
If Doxygen and the Python packages Sphinx, Breathe, and Exhale (see
Dependencies above) are all found at configure time, cmake
--build build (with no explicit --target) builds this documentation
site too, into doc/html, alongside everything else – if they aren’t
found, that step is simply skipped, with a note printed at configure time,
and every other target is unaffected. To build just the documentation
without touching anything else:
cmake --build build --target docs
or, from doc/sphinx directly, without going through CMake at all – though
in this case slugPython must already have been built (cmake --build
build --target docs above builds it automatically first; this page’s own
autodoc-generated content, e.g. The slug Python API, imports slugpy,
which fails without it):
cmake --build build --target slugPython cd doc/sphinx make html