|
Uni20
Asynchronous tensor and runtime library.
|
Status: current implementation and build guide.
The current uni20 extension is a nanobind smoke module. It exposes greet() and generated build metadata; it does not yet expose Tensor values, numerical operations, NumPy or DLPack interop, or native async values.
Importing the extension configures recoverable Uni20 ERROR, ERROR_IF, and trace::raise(...) paths to throw exceptions process-wide. Nanobind translates exceptions crossing a synchronous binding boundary into Python exceptions.
Internal invariant failures reported by CHECK, PRECONDITION, or PANIC still abort. Future Tensor bindings must validate user-controlled values before entering native paths whose contracts assume valid input. Future asynchronous bindings must retain exceptions in native async state and deliver them through the Python result instead of allowing them to escape a worker thread.
Kernel bindings should use dynamic_dispatch_kernel(...) where an operation may be absent from a configured build. This preserves the native compile-time dispatch contract while translating an unavailable binding instantiation into KernelDispatchError.
The Python layer will bind Uni20 operations; it will not define a parallel tensor, storage, device, dispatch, or scheduler architecture.
The native contracts remain authoritative:
Tensor and TensorView define values, views, ownership, accessors, and storage-derived backend selection.Async<T> defines asynchronous value and alias semantics.The representation of arbitrary-rank tensors, NumPy/DLPack API spelling, device exposure, and Python async API remain open design questions. They should be decided when implementing the corresponding binding, against the then current native API and protocol versions.
See Tensor Operations, Async Storage, and Kernel Dispatch.
Before configuring the project ensure the following are available:
Python 3.11 or newer with development-module headers. On Debian-based systems:
Uni20 reuses the same BLAS/LAPACK dependencies as the core C++ library. The configuration step discovers Python first and then requires nanobind 2.13.0 or newer from a system installation, falling back to nanobind v2.13.0 through CMake FetchContent.
Enable the bindings when configuring:
Build the extension target directly, or build the default target graph:
The compiled module is written under build/bindings/python/. On Linux and macOS the filename follows the normal ABI-tagged extension naming convention such as uni20.cpython-312-x86_64-linux-gnu.so.
The sample module currently exports a greet() helper together with build metadata. Add the build output directory to PYTHONPATH and import it directly:
Expected output:
The Python example provides the same setup as a runnable script.
The Python buildinfo() function exposes the same generated metadata as the C++ <uni20/buildinfo.hpp> API:
For a formatted string:
For the C++ API and pretty-print example, see Build Information.
Future Tensor bindings use the common C++ presentation data for human-facing output while keeping terminal text, plain text, and notebook HTML as separate renderers.
Design rules for future Python display:
repr(obj) should be stable, plain, and safe for large tensors.str(obj) and print(obj) may use presentation defaults, but should avoid surprising exhaustive output._repr_html_() or _repr_mimebundle_() should be used for rich Jupyter display when available.obj.pretty(...) should expose explicit controls such as width, glyphs, charset, color, selected axes, precision, and preview limits.UNI20_GLYPHS, UNI20_CHARSET, UNI20_COLOR, NO_COLOR, and COLUMNS should provide defaults, but per-call Python overrides should win.Tensor and mdspan display in Python must be preview-first. Do not bind a tensor repr to the current exhaustive mdspan formatter by default. Add an explicit preview policy first, with limits such as maximum elements, edge items, maximum rows/columns, maximum slices, and an opt-in full-output mode.
Future arithmetic bindings should follow the Python Dtype Promotion design note rather than acquiring promotion behavior accidentally from nanobind conversions.
The Python bindings ship with lightweight smoke tests that import the compiled extension and validate both greet() and the generated build information:
If you prefer to run a smoke test directly, pass the directory containing the compiled extension so the test can add it to sys.path:
Adjust the second argument if your build directory differs.
The repository currently builds a top-level uni20 extension through CMake. It does not yet ship a pyproject.toml, wheel-building backend, generated stubs, or packaged Python distribution.