Releases: odlgroup/odl
Release list
ODL 1.0.0
(This is a re-publication of same 1.0.0 release as earlier today, due to a failure of the Github-Actions script that should have uploaded it to PyPI)
Finalized version of the restructuring that makes ODL capable of natively using different array backends and -devices.
Besides fixing small bugs in the previous beta releases and completing some changes required to make operators backend-agnostic (particularly the finite-difference operators), this version introduces a new feature to make switching between backends practical in a operator pipeline: adapters.
See https://odl.readthedocs.io/guide/numpy_guide.html#switching-between-array-backends.
It also gives better control over the test suite (testing all available backends and devices can take a long time; there are now command-line options to test only particular combinations), enables using the UV package manager for all development tasks, and includes a general code cleanup.
ODL 1.0.0
Finalized version of the restructuring that makes ODL capable of natively using different array backends and -devices.
Besides fixing small bugs in the previous beta releases and completing some changes required to make operators backend-agnostic (particularly the finite-difference operators), this version introduces a new feature to make switching between backends practical in a operator pipeline: adapters.
See https://odl.readthedocs.io/guide/numpy_guide.html#switching-between-array-backends.
It also gives better control over the test suite (testing all available backends and devices can take a long time; there are now command-line options to test only particular combinations), enables using the UV package manager for all development tasks, and includes a general code cleanup.
v1.0.0b1
1.0.0b0
ODL 1.0.0b – Beta Release Notes (2025-11-07)
Today, we are happy to ship the ODL 1.0 Beta, a new version focused on GPU computations with PyTorch. The main feature in this release is the refactoring that allows the use of different backends for handling multi-dimensional arrays. Previous versions of ODL relied entirely on NumPy for this purpose. This release enables other backends and we use this to include support for PyTorch. As a result, ODL can now be used in high-performance computations as this reduces CPU–GPU copying. Two minimal examples of this integration can be found here and there.
New features:
- New PyTorch backend for ODL. Specifying the backend and the device on which the data is stored is as simple as
odl.rn(*, impl='pytorch', device='cuda:0'). - For performance purpose, we ensured that the data remains tied to the TensorSpace and will not be copied across devices without explicit conversion.
- Using the Python Array API standard, we now have a trivial way to switch between backends. Entire pipelines can be written with ODL functions and the switch between implementations and devices depends only on the space.
- Future-proofing ODL using the Python Array API everywhere possible. This clarifies the code, simplifies maintenance and development as well as opening the door to other backends, such as JaX and CuPy.
- Tighter integration of ASTRA using the DLPack framework.
API change:
A migration guide is available here, but there are two key changes introduced in 1.0:
- Replacement of NumPy ufunc calls by new ODL functions, providing a unified way to call functions across backends. The signature of these functions follows the Python Array API.
- We reorganised ODL’s package hierarchy to better separate ODL core math functionalities and application-specific modules.
Breaking changes:
- One cannot call NumPy functions on ODL objects anymore. Instead, we now provide such functions in the odl namespace. E.g.:
np.sin()becomesodl.sin()
This change is the most significant that ODL has undergone since 0.8. The previous version was too limiting as it tied ODL to NumPy. As such a user wanting to port their ODL pipeline to support PyTorch arrays would have needed to rewrite their entire script. To avoid such a tedious task, we created a set of functions following the Python Array API, allowing us to define a pipeline entirely with ODL functions. - Basic arithmetic operations between ODL objects and backend-specific arrays are not permitted anymore. This is to ensure that no device–backend transfers are done under the hood and undermine performance. Users must wrap any array in ODL
TensorSpaceelements to integrate them into pipelines.
Future API changes:
- The
*operation will be deprecated in favour of@for the composition ofOperators. Historically, ODL has used the*operator for the matrix multiplication. This was inconsistent with other libraries that refer to the Hadamard product using*. As of ODL 1.1, we will remove the use of*to compose operators together.
Future features:
- To support multiple devices and backends, we will create a new
Operator-like class to allow switching between backends and devices that can be composed with other ODL operators to create consistent pipelines. - We will optimise the autograd engine by exploiting PyTorch’s optimised routines for Operators that only rely on Python Array API-compatible functions and only falling back to manually defined gradients for Operators relying on third-party libraries (like ASTRA).
- Image deformations: LDDMM based deformations with KEOpS as backend.
- Positron emission tomography (PET): Data structures for PET data and integration with parallelproj as backend for PET forward projections
- Reinforce testing pipelines to ensure numerical consistency between backends.
Rough Edges
While these significant changes to the codebase pass our large suite of unit tests, we expect that some corner cases will create errors after the release. This is why we put this version under the “Beta” umbrella and will make a definitive 1.0 version after getting initial feedback. Please check the migration guide, the examples, and reach out to us so we can work out solutions.
The suspected rough edges are the following:
- In our test pipeline, we test ODL’s computations against backend-specific functions. That is, the comparison is always within backends. For certain cases, there might be small discrepancies across backends, and their magnitude is currently not quantified.
- In some cases, we rely on explicit copies to ensure the consistency between a space’s properties and its array data. Although these copies are restricted to single devices, they might represent an overhead, memory and time wise, compared to their pure-PyTorch or NumPy equivalents.
- It is not guaranteed that PyTorch
autogradwill work on any ODLOperator. This only works when the underlying operation are actually implemented in pure-PyTorch and we cannot guarantee this behaviour accross the entire library.
@leftaroundabout and @Emvlt worked really hard on this release, and we hope that you will enjoy it. 😊
ODL 0.8.3
ODL 0.8.2
This is another minor release to improve compatibility, without changing functionality compared to ODL-0.8.
- This version is compatible with NumPy-2.0 and NumPy-2.1. Previously, only NumPy-1.26 and older were supported. NumPy-2 support is significant in particular because it unlocks using the Python Array API, which will in the future be used to switch between backends other than NumPy, particularly PyTorch.
- Small fixes that prevented testing, both regarding new PyTest versions and floating-point accuracy.
We have identified that NumPy-2 has some subtle precision differences compared to NumPy-1 when using small float types (float16 / float32). That means that tight equality checks might need to be modified. This is not a change from ODL itself but from the underlying NumPy computations. If you experience problems with this, it is still possible to build this ODL version against NumPy-1.26, but it should be seen as a temporary fix because ODL may in the future drop NumPy-1 support.
ODL 0.8.1
This release mostly fixes a small incompatibility with the PyFFTW library versions >=0.13 involving wrong normalisation constants.
ODL 0.8.0
Despite the long time that has passed since v0.7.0, this is a minor release. Its sole purpose is to provide an easily installable form of ODL as it was in 0.7, but updated to be compatible with modern versions of the libraries we depend on (in particular NumPy and SciPy, which have made several breaking changes since).
The reason this version is still numbered 0.x is that ODL itself will soon have to undergo changes that may break existing user code. The upcoming version 1.0 is intended to move away from the current status where essentially all computational objects are wrappers around NumPy arrays, and instead be more agnostic with respect to the backend. This will both allow faster execution of existing inverse-modelling setups by keeping data on e.g. a GPU, as well as tighter integration with deep learning frameworks. The implementation of this for PyTorch is work in progress. It does however require forgoing some of the convenience utilities that made ODL space-elements almost perfect drop-in replacements for NumPy arrays.
This is the final release which prioritises allowing NumPy-designed algorithms to be used on ODL objects.
ODL 0.7.0
This release is a big one as it includes the cumulative work over a period of 1 1/2 years. It is planned to be the last release before version 1.0.0 where we expect to land a number of exciting new features.
What follows are the highlights of the release. For a more detailed list of all changes, please refer to the release notes in the documentation.
Native multi-indexing of ODL space elements
The DiscreteLpElement and Tensor (renamed from FnBaseVector) data structures now natively support almost all kinds of Numpy "fancy" indexing.
At the same time, the spaces DiscreteLp and Tensorspace (renamed from FnBase) have more advanced indexing capabilities as well. Up to few exceptions, elem[indices] in space[indices] is always fulfilled.
Alongside, ProductSpace and its elements also support more advanced indexing, in particular in the case of power spaces.
Furthermore, integration with Numpy has been further improved with the implementation of the __array_ufunc__ interface. This allows to transparently use ODL objects in calls to Numpy UFuncs, e.g., np.cos(odl_obj, out=odl_obj) or np.add.reduce(odl_in, axis=0, out=odl_out) — both these examples were not possible with the __array__ and __array_wrap__ interfaces.
Unfortunately, this changeset makes the odlcuda plugin unusable since it only supports linear indexing. A much more powerful replacement based on CuPy will be added in version 1.0.0.
Integration with deep learning frameworks
ODL is now integrated with three major deep learning frameworks: TensorFlow, PyTorch and Theano. In particular, ODL Operator and Functional objects can be used as layers in neural networks, with support for automatic differentiation and backpropagation. This makes a lot of (inverse) problems that ODL can handle well, e.g., tomography, accessible to the computation engines of the deep learning field, and opens up a wide range of possibilities to combine the two.
The implementation of this functionality and examples of its usage can be found in the packages tensorflow, torch and theano in the odl.contrib sub-package (see below).
New contrib sub-package
The core ODL library is intended to stay focused on general-purpose classes and data structures, and good code quality is a major goal. This implies that contributions need to undergo scrutiny in a review process, and that some contributions might not be a good fit if they are too specific for certain applications.
For this reason, we have created a new contrib sub-package that is intended for exactly this kind of code. As of writing this, contrib already contains a number of highly useful modules:
datasets: Loaders and utility code for publicly available datasets (currently FIPS CT, Mayo clinic human CT, Tu Graz MRI and some image data)fom: Implementations of Figures-of-Merit for image quality assessmentmrc: Reader and writer for the MRC 2014 data format in electron microscopyparam_opt: Optimization strategies for method hyperparameterspyshearlab: Integration of thepyshearlabPython library for shearlet decomposition and analysisshearlab: Integration of theShearlab.jlJulia shearlet librarysolvers: More exotic functionals and optimization methods than in the core ODL librarytomo: Vendor- or application-specific geometries (currently Elekta ICON and XIV)tensorflow: Integration of ODL with TensorFlowtheano: Integration of ODL with Theanotorch: Integration of ODL with PyTorch
Overhaul of tomographic geometries
The classes for representing tomographic geometries in odl.tomo have undergone a major update, resulting in a consistent definition of coordinate systems across all cases, proper documentation, vectorization and broadcasting semantics in all methods that compute vectors, and significant speed-up of backprojection due to better axis handling.
Additionally, factory functions cone_beam_geometry and helical_geometry have been added as a simpler and more accessible way to create cone beam geometries.
ODL 0.6.0
Besides many small improvements and additions, this release is the first one under the new Mozilla Public License 2.0 (MPL-2.0).
For a more detailed list of changes, see the release notes.