Skip to content

Repository files navigation

libparallelproj logo

libparallelproj

Build and Test Build CUDA Build Documentation
Documentation Status Code Coverage License Latest Tag conda-forge version

libparallelproj is a high-performance library for 3D forward and backward projection, supporting both CUDA and non-CUDA builds and a minimal python interface.

Official documentation: https://libparallelproj.readthedocs.io

Table of Contents


Installation

We recommend to install pre-compiled versions of libparallelproj from conda-forge where cuda 12/13 and non-cuda builds are available (see official docs).

Build requirements

The recommended way to build from source is with pixi, which manages all toolchain and library dependencies (compiler, CMake, Ninja, nanobind, CUDA toolkit, …) automatically.

If you prefer to drive CMake directly, install the dependencies listed below yourself and use the presets in CMakePresets.json.

Dependencies (only needed without pixi)

Category Requirement
Build tools CMake ≥ 3.18, Ninja, C++17 compiler
Non-CUDA builds OpenMP
Python extension Python ≥ 3.12, nanobind
CUDA builds CUDA Toolkit 12 or 13
Testing pytest, numpy, array-api-compat, array-api-strict, pytorch
Documentation Doxygen, Sphinx ≥ 8, breathe, furo, sphinx-gallery, …

Building the Project

Recommended: build with pixi

pixi resolves and installs all dependencies into isolated environments. Each environment (default, cuda12, cuda13, docs) exposes the same set of tasks:

Non-CUDA build (CPU / OpenMP, all platforms):

pixi run -e default configure   # cmake --preset non-cuda
pixi run -e default build       # cmake --build build
pixi run -e default test        # ctest + pytest
pixi run -e default install     # cmake --install build

CUDA build (requires a CUDA 12 or 13 driver on the machine):

# CUDA 12
pixi run -e cuda12 configure    # cmake --preset cuda12
pixi run -e cuda12 build
pixi run -e cuda12 test

# CUDA 13
pixi run -e cuda13 configure    # cmake --preset cuda13
pixi run -e cuda13 build
pixi run -e cuda13 test

All available tasks:

Task Description
configure CMake configure (uses the environment's preset)
build CMake build
test-cpp C++ tests via ctest
test-python Python tests via pytest
test Both test suites
install cmake --install
uninstall Remove installed files (default env only)

The default environment additionally provides configure-coverage, test-python-cov, and collect-coverage-cpp for coverage reporting.

Alternative: build directly with CMake

Install the dependencies listed above yourself, then use the CMake presets directly:

# Non-CUDA
cmake --preset non-cuda
cmake --build build
ctest --output-on-failure --test-dir build

# CUDA 12
cmake --preset cuda12
cmake --build build-cuda12

# CUDA 13
cmake --preset cuda13
cmake --build build-cuda13

See CMakePresets.json for all preset options.

Notes

  • Both cuda12 and cuda13 presets use CMAKE_CUDA_ARCHITECTURES=native. For builds targeting multiple GPU generations, override with all or all-major — see the CMake docs.
  • The Python extension build can be disabled by passing -DBUILD_PYTHON=OFF to the configure step.

Building the docs with Sphinx

With pixi (recommended):

pixi run -e docs build-docs

This runs the full chain: CMake configure → Doxygen XML → full project build → sphinx-build. The output is written to docs/_build/html.

Without pixi: install the documentation dependencies and run:

cd docs && make html

Using libparallelproj from another CMake project

After installing libparallelproj, downstream CMake projects can locate it via:

find_package(parallelproj CONFIG REQUIRED)

This provides the imported CMake target:

parallelproj::parallelproj

which should be linked to your executable or library.

Minimal example

cmake_minimum_required(VERSION 3.18)
project(my_project LANGUAGES C CXX)

find_package(parallelproj CONFIG REQUIRED)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE parallelproj::parallelproj)

If CMake cannot find the package

If libparallelproj was installed into a non-standard location, point CMake to the installation prefix:

cmake -S . -B build -DCMAKE_PREFIX_PATH=/path/to/libparallelproj/install

CMake will then look for the installed package configuration files in the corresponding install tree.

Package version selection

You can request a minimum version in find_package, for example:

find_package(parallelproj 2.0 CONFIG REQUIRED)

The exported package version is numeric, for example 2.0.2, so standard CMake version matching works as expected.

Available CMake variables

After calling

find_package(parallelproj CONFIG REQUIRED)

the following variables are available:

  • PARALLELPROJ_CUDA 1 if libparallelproj was built with CUDA support, otherwise 0

  • PARALLELPROJ_VERSION Numeric package version, for example 2.0.2

  • PARALLELPROJ_INCLUDE_DIRS Install include directory

  • PARALLELPROJ_LIBRARY_DIRS Install library directory

  • PARALLELPROJ_VERSION_STRING full (more descriptive) package version containing labels for "dirty" versions, for example 2.0.2-dirty-0-12ab3

In most cases, it is best to link against the imported target parallelproj::parallelproj rather than manually using include and library directory variables.

Checking whether the installed library was built with CUDA

At CMake configure time:

find_package(parallelproj CONFIG REQUIRED)

if(PARALLELPROJ_CUDA)
  message(STATUS "parallelproj was built WITH CUDA support")
else()
  message(STATUS "parallelproj was built WITHOUT CUDA support")
endif()

At runtime, the linked library can be queried via the C API:

#include "parallelproj.h"

if (parallelproj_cuda_enabled()) {
    /* built with CUDA support */
} else {
    /* built without CUDA support */
}

// full version string (the content of the VERSION file, e.g. "2.1.0" or "2.0.6.dev0")
const char* version = parallelproj_version();

// the numeric version components can be checked via
int pp_major_version = parallelproj_version_major();
int pp_minor_version = parallelproj_version_minor();
int pp_patch_version = parallelproj_version_patch();

Note:

  • parallelproj_version() returns the full version string, which for dev builds includes a .devN suffix (e.g. 2.0.6.dev0).

Versioning and release procedure

The VERSION file at the repo root is the single source of truth for the project version (PEP 440 style: X.Y.Z for releases, X.Y.Z.devN between releases). CMake, the Python extension, the docs, and the conda recipes all derive their version from it.

To make a release:

  1. open a release PR that bumps VERSION to the release version (e.g. 2.1.0) and adds a v2.1.0 entry to docs/changelog.rst, then merge it
  2. on the up-to-date main branch run pixi run tag-release — this creates the annotated tag v2.1.0 after validating that the working tree is clean, VERSION is a non-dev version, and the changelog entry exists
  3. publish the tag with git push origin v2.1.0 — the check_version workflow re-verifies that the tag matches VERSION (mismatched tags fail CI before any release artifacts exist)
  4. open a follow-up PR bumping VERSION to the next dev version (e.g. 2.1.1.dev0)

The conda-forge feedstock derives its version from the release tag, which the guards above guarantee to be identical to the VERSION file.

About

C++/CUDA backend and minimal python interface for projectors

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages