|
Uni20
Asynchronous tensor and runtime library.
|
Welcome to uni20. This repository contains an early-stage tensor-network library written in C++23 with optional BLAS, CUDA, benchmark, documentation, and Python binding support. This guide covers the current CMake-based workflow for configuring, building, testing, benchmarking, and generating documentation.
A brief overview of the directory layout:
Before building the project, ensure you have the following installed:
Note: Uni20 prefers system installations of
fmt,TBB, Google Benchmark, and other optional dependencies when compatible versions are available. Otherwise CMake can fetch missing dependencies from source during configuration.
Optional developer packages such as libbenchmark-dev and libgtest-dev can also be installed from the system, but Uni20 can fetch them automatically when needed. Install libtbb-dev only when it provides oneTBB 2022.3 or newer, and install libfmt-dev only when it provides fmt 11.1 or newer. Ubuntu 24.04's oneTBB 2021.11 and fmt 9.1 packages are too old.
Use an out-of-source build. From the project root, run:
If you prefer Ninja and have it installed:
Common configuration toggles include:
Uni20 uses CMake's FindBLAS and FindLAPACK modules to locate a compatible BLAS/LAPACK implementation. Use -DUNI20_BLAS_VENDOR=<vendor> to forward a vendor hint to BLA_VENDOR when you want to prefer a specific implementation such as OpenBLAS or an Intel MKL variant.
Vendor extension APIs are opt-in:
The generic BLAS wrappers remain available through uni20::blas. When enabled, vendor utility functions are exposed under uni20::blas::openblas and uni20::blas::mkl. For Uni20's async runtime, prefer UNI20_BACKEND_MKL_SEQUENTIAL=ON unless you explicitly want MKL to run its own internal worker threads. UNI20_BACKEND_MKL=ON remains as a compatibility option and selects the sequential MKL backend unless a specific MKL variant is enabled.
Configure a CUDA build with the CUDA language and backend enabled:
The hello-world example reports the CUDA toolkit, driver, visible devices, and Uni20 backend capabilities. It also installs the runtime described below and exercises each enrolled device's stream/completion resources.
A CUDA application explicitly installs one process-wide resource service near the start of main():
Retain the returned cuda::Runtime guard for as long as any CUDA Tensor, buffer, stream, provider lease, or CUDA task exists. The runtime is not passed through Tensor operations: ordinary extent-only CudaTensor construction uses its configured default device, while cuda::device_resources(device) selects another enrolled device for explicit construction.
CudaTensor describes device storage; it does not choose blocking versus coroutine execution. A direct Tensor matrix product may block while acquiring an idle cuBLAS handle and stream, then returns after publishing the queued CUDA work to the buffers' completion ledgers. Wrapping the same type in Async<CudaTensor> selects coroutine-aware dispatch: its CudaTask awaits those resources without blocking a scheduler participant.
By default, cuda::initialize() enrolls every visible device, chooses the first enrolled device as the default, and creates eight actually-idle streams per device. RuntimeConfig::device_ordinals, default_device, streams_per_device, and stream_flags customize that installation. Only one runtime may be active in a process. Direct cuda::DeviceResources construction is reserved for focused tests and low-level bring-up.
The CUDA API and Tensor aliases are available only in CUDA-enabled builds. See the CUDA Runtime Foundation for lifetime and resource contracts and CUDA Buffers for the stream-synchronized access model used by backend authors.
Uni20 generates build metadata for both C++ and Python. In C++:
For a terminal report:
See Build Information for the full C++ and Python API shape.
Uni20 ships a large GoogleTest-based suite and registers the per-module tests with CTest.
You can run tests using either CTest or by executing test binaries directly. The test system supports both separate (per-module) test executables and an optional combined test binary.
See Testing for detailed configuration options, test architecture, and best practices.
Tests are enabled by default. After building:
This runs all tests registered with CTest. The optional combined uni20_tests executable is built for manual runs, but it is not registered with CTest by default.
To filter tests by name or suite:
You may also run test executables manually. For example:
The Google Test interface supports additional flags (e.g., --gtest_list_tests) for exploring and selecting tests interactively.
To disable all tests or change test modes, pass options to CMake during configuration:
See Testing for a full explanation of these options and how they affect the build.
The project uses Google Benchmark for performance measurement.
Uni20 provides a run_benchmarks helper target:
Or run the benchmark executable directly:
Benchmarks will output performance metrics (execution time, iterations, etc.) to the console.
The Python extension is built with nanobind. Configure with -DUNI20_BUILD_PYTHON=ON and either build the default target graph or the extension target directly:
The compiled extension is written under build/bindings/python/. To try the sample binding:
For more detail see Python Bindings.
To help maintain a consistent code style across the project, we've integrated clang-format and several other configuration tools. This section outlines the code formatting preferences, how to use clang-format from the command line (and in your editor), and highlights other recent enhancements.
The project uses clang-format to enforce a consistent code style, although the formatting isn't compulsory. A sample .clang-format file is provided at the root of the repository with the following key style settings:
To streamline formatting, we have created a separate CMake module in cmake/ClangFormat.cmake. This module defines a custom target that automatically runs clang-format on all source files. The module looks for all C++ source and header files (in src/, tests/, and bindings/python/) and creates a target named clang_format.
You can run the formatting target with:
This will invoke clang-format in-place on all matching files. Many editors have some form of clang-format integration, which may be helpful.
UNI20_) to enable or disable features such as CUDA, MPI, testing, and benchmarking.FetchContent. UNI20_FETCHCONTENT_BASE_DIR controls build and stamp files. UNI20_FETCHCONTENT_SOURCE controls whether fetched sources live under the build directory or a shared cache rooted at UNI20_FETCHCONTENT_SOURCE_BASE_DIR.ctest --test-dir build. The top-level build tree already includes the discovered tests; no extra --recursive flag is required.Contributions to uni20 are welcome! Please follow these steps:
feature/new-backend).For further details, see the Contributor Guide.