Install#
Python users need only pip install dyng (section Python below). The rest of the
page builds the C++ library from source, with or without CUDA, and uses it from CMake.
Requirements#
Tool |
Version |
|---|---|
Operating system |
Linux (x86-64); other platforms are untested |
C++ compiler |
GCC 11 or newer, or Clang 15 or newer (CI builds with GCC 12/13 and Clang 17/18) |
CMake |
3.30 or newer, and Ninja |
OpenMP |
optional; enables the |
Python |
3.12 or newer, for the Python package (NumPy >= 1.26) |
CUDA |
optional; the toolkit 12.4 or newer builds the |
The conda environment in environment.yml provides CMake, Ninja, the formatters, Doxygen and
the documentation tools at the versions CI uses; the compiler and the CUDA toolkit come from the
system.
Build from source#
git clone https://github.com/dyng-dev/dyng.git
cd dyng
conda env create -f environment.yml # once; `conda env update -f environment.yml` after it changes
source scripts/dev_env.sh # activates dyng-dev, adds nvcc if present, sets DYNG_SCRATCH
cmake --preset dev # Debug, tests on, warnings as errors
cmake --build --preset dev
ctest --preset dev # unit, randomized and fixture-parity tests (no GPU)
Presets (cmake --list-presets):
Preset |
Use |
|---|---|
|
Debug development build: tests on, warnings as errors, allocation budgets on |
|
Release build of the CPU backends (hosted CI, the CPU wheel) |
|
optimized builds |
|
host sanitizers (AddressSanitizer + UBSan; ThreadSanitizer with OpenMP off; ThreadSanitizer with OpenMP, Clang and Archer) |
|
the flags of the original research codes, for parity and performance runs |
ci/check.sh runs the whole local gate (formatting, the cpu-only and dev presets, the
clang-tidy naming checks, REUSE, the documentation build and pre-commit); the hosted workflows
lint, cpu and docs run the same steps on every pull request.
Build with CUDA#
The CPU presets never build CUDA. With the CUDA toolkit on PATH (scripts/dev_env.sh adds
/usr/local/cuda-13.1/bin when it exists; set DYNG_CUDA_HOME for another toolkit), the CUDA
presets build the library with the cuda backend next to the CPU ones:
cmake --preset dev-cuda # Debug, this machine's GPUs (native), host code -Werror
cmake --build --preset dev-cuda
ctest --preset dev-cuda -L gpu # the CUDA tests (they need a visible GPU)
Preset |
Use |
|---|---|
|
CUDA development: Debug, |
|
the release architecture list (sm_75 to sm_120 SASS plus PTX) |
|
the flags of MOSP-CUDA ( |
|
for |
|
the compile-only builds of the hosted |
DYNG_CUDA_ARCHITECTURES chooses native (the default; without a visible GPU the configure
step warns and uses the release list), release or an explicit list such as 86.
ci/gpu_local.sh is the local GPU gate (the CUDA tests, the golden corpus on the cuda backend,
compute-sanitizer); the hosted cuda-build workflow compiles the CUDA presets with CUDA 13
and 12 but runs no test, because hosted runners have no GPU.
Use dynG from CMake#
Install a build (cmake --install build/cpu-only --prefix <prefix>) and find it from your
project:
find_package(dyng 0.3 REQUIRED)
target_link_libraries(my_app PRIVATE dyng::dyng)
Before 1.0 a minor release may break the API, so the package accepts only a request of its own
minor version: find_package(dyng 0.3) finds 0.3.x (the development versions and release
candidates included) and refuses 0.2 and 0.4. A build of the 0.2.0 release (the tag v0.2.0)
asks for find_package(dyng 0.2 REQUIRED); this page describes main.
Or add the source tree with add_subdirectory(); the target name is the same. Everything is in
namespace dyng, and #include <dyng/dyng.hpp> includes the whole public API
(C++ API).
Python#
The Python package dyng is one wheel for CPython 3.12 and newer on Linux x86-64 (abi3,
manylinux_2_28; OpenMP’s runtime is bundled). It contains the sequential and OpenMP backends and
the dyng command line (Command-line interface); NumPy is its only dependency.
pip install dyng # from PyPI (0.2.0)
python -c "import dyng; dyng.show_config()"
An environment that has an earlier release keeps it unless pip is told to upgrade: pip install -U dyng (and pip install -U "dyng[cu13]" for the plugin, below).
The same package can be built from a clone (it compiles the C++ core, so it needs CMake >=
3.30 and Ninja, for example from the dyng-dev environment, and a C++17 compiler from the
system):
pip install . # the wheel of this checkout
python -m build # or: the sdist and the wheel into dist/
For development, an editable install rebuilds the extension when dyng is imported after a C++
change:
source scripts/dev_env.sh
pip install -e . --no-build-isolation -Ceditable.rebuild=true -Cbuild-dir=build
ci/python.sh # the editable install, the stubs check, mypy, pytest
dyng.show_config() prints the backends of the active native module; dyng.Resources("cuda")
raises NotSupportedError in the CPU wheel. The PyPI release 0.0.1 was only the name
reservation and contains no library. A first update in Python runs a first update; the local
build of the release wheels is described in Wheels, the sdist and the release workflow.
CUDA from Python: the plugin wheels#
From 0.2 the CUDA backend comes as a plugin wheel next to dyng: dyng-cu13 for an NVIDIA
driver of CUDA 13, dyng-cu12 for CUDA 12 (ADR 0030). The extras install the plugin of the same
version:
pip install "dyng[cu13]" # NVIDIA driver 580 or newer (CUDA 13.x)
pip install "dyng[cu12]" # NVIDIA driver 525 or newer (CUDA 12.x)
python -c "import dyng; dyng.show_config()"
Upgrading from 0.1.0: pip install -U "dyng[cu13]" (or "dyng[cu12]"). Without -U, pip
treats the installed dyng 0.1.0 as satisfying the requirement, only warns that 0.1.0 does not
provide the extra cu13, and installs neither 0.2.0 nor the plugin (0.1.0’s own error message
for Resources.cuda() names the line without -U).
A plugin contains the CUDA runtime (no CUDA toolkit is needed), code for the GPU architectures
sm_75 to sm_120 (Turing to Blackwell) and PTX for newer ones. Which one to install: nvidia-smi
prints the driver’s “CUDA Version”; take the plugin of that major (a cu12 plugin also runs on a
CUDA 13 driver; a cu13 plugin needs a CUDA 13 driver). With both installed, the one of the
driver’s CUDA major is used.
|
Install |
Built with |
|---|---|---|
13.x (driver 580.65.06 or newer) |
|
CUDA 13.4 |
12.x (driver 525.60.13 or newer) |
|
CUDA 12.9 |
older, or no NVIDIA GPU |
|
Requirements: Linux x86-64 with glibc 2.28 or newer (manylinux_2_28), CPython 3.12 or newer, an
NVIDIA GPU of compute capability 7.5 or newer (Turing, 2018, and later; the CUDA 13 toolkits no
longer support older GPUs), and the NVIDIA driver. CUDA’s minor-version compatibility lets a
plugin built with the latest toolkit of its major run on any driver of that major. In a
container the GPU and the driver’s libraries must be passed in (docker run --gpus all, the
NVIDIA Container Toolkit). The optional extras cupy-cu13 / cupy-cu12 and torch install
CuPy and PyTorch for the device-array round trips.
import dyng
res = dyng.Resources.cuda(device=0) # or Resources.cuda(stream=torch_or_cupy_stream)
g = dyng.Graph.from_edges([0, 0, 1], [1, 2, 2], [4, 1, 1], resources=res)
tree = dyng.sssp.compute(g, 0)
print(tree.distances.device, tree.distances.to_numpy()) # cuda:0 [0 4 1]
Results of the CUDA backend stay in device memory: torch.from_dlpack(tree.distances) and
cupy.asarray(tree.distances) view them without a copy, and to_numpy() copies them to the host
(Python API).
Troubleshooting. dyng.show_config() names the active module (dyng_cu13 (plugin cu13) or
dyng._core), why it was chosen, and the state of every installed plugin. If a plugin is
installed but cannot be used, dynG runs on the CPU backends and issues one dyng.BackendWarning
with the reason:
Reason in the warning |
Remedy |
|---|---|
|
install the NVIDIA driver (in a container: run it with the GPU, e.g. |
|
update the driver, or |
|
check |
|
the plugins need compute capability 7.5 or newer (Turing and later): use the CPU backends ( |
|
|
|
reinstall the plugin; report the message if it persists |
|
no plugin is installed, or the warning above says why it is not used |
Errors of the CUDA backend itself (a dyng.CudaError or NotSupportedError after the plugin was
chosen):
Message |
Cause and remedy |
|---|---|
|
a worker process started with |
|
the device is not covered by the plugin’s architectures (sm_75 to sm_120, PTX for newer ones); with several GPUs, choose a supported one with |
On a machine without a GPU (a CI runner, a login node) an installed plugin is harmless: dynG
falls back to the CPU backends with the warning; set DYNG_CPU_ONLY=1 there to silence it.
DYNG_CPU_ONLY=1 in the environment (also true, yes or on, in any case; 0, false,
no, off or empty leave the choice to dynG, and any other value is ignored with a
dyng.BackendWarning), or dyng.use_cpu_only() before the first use of dynG,
chooses the CPU backends without the warning; warnings.filterwarnings("ignore", category=dyng.BackendWarning) silences it. Building a plugin from source is described in
Wheels, the sdist and the release workflow.