Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2.0.0
-----
MAJOR UPDATE: PyTorch 2.x Modernization
- Added support for PyTorch 2.x (tested with PyTorch 2.10)
- Added support for Python 3.10, 3.11, 3.12
- Added torch.compile support (works with expected warnings for C++ extensions)
- Fixed critical GIL handling bug in PyCapsule creation that caused segfaults
- Replaced deprecated torch.Tensor() with torch.empty(0)
- Updated metadata and requirements for modern Python/PyTorch
- Added example_torch_compile.py demonstrating torch.compile usage
- Dropped support for Python 3.6, 3.7, 3.8, 3.9
- Dropped support for PyTorch < 2.0

1.2.7
-----
Added support for PyTorch 1.10.0, 1.10.1, 1.11.0
Expand Down
138 changes: 138 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Signatory 2.0 Migration Guide

## Overview

Signatory 2.0 is a major update that modernizes the library for PyTorch 2.x. This guide explains the changes and how to migrate from Signatory 1.x.

## What's New in 2.0

### PyTorch 2.x Support
- Full compatibility with PyTorch 2.x (tested with PyTorch 2.10)
- Works with NVIDIA PyTorch containers and modern PyTorch installations
- Support for torch.compile (with expected warnings for C++ extensions)

### Python Version Updates
- Now requires Python 3.10 or higher (3.10, 3.11, 3.12)
- Dropped support for Python 3.6, 3.7, 3.8, 3.9

### Critical Bug Fixes
- **Fixed GIL handling bug**: The PyCapsule creation in `make_lyndon_info` was incorrectly releasing the GIL before calling Python C API functions, causing segmentation faults. This is now fixed by properly scoping the GIL release.
- **Deprecated API updates**: Replaced `torch.Tensor()` with `torch.empty(0)` for empty tensor creation

### New Features
- torch.compile support with Signatory operations
- New example: `examples/example_torch_compile.py` demonstrating torch.compile usage
- Updated metadata and installation instructions

## Installation

### From Source (Recommended for 2.0)

```bash
git clone https://github.com/patrick-kidger/signatory.git
cd signatory
git checkout pytorch-2.10-modernization
pip install -e . --no-build-isolation
```

### Requirements

- Python 3.10, 3.11, or 3.12
- PyTorch 2.x
- Linux or Windows
- CUDA (optional, for GPU acceleration)

## API Changes

### No Breaking Changes

The core API remains unchanged! Your existing code using Signatory 1.x will work with Signatory 2.0 without modifications:

```python
import signatory
import torch

# This works exactly the same as in 1.x
path = torch.rand(8, 10, 3)
signature = signatory.signature(path, depth=4)
logsignature = signatory.logsignature(path, depth=4)
```

### New Capabilities

#### torch.compile Support

You can now use torch.compile with models that include Signatory operations:

```python
import signatory
import torch
from torch import nn

class SigNet(nn.Module):
def __init__(self):
super().__init__()
self.sig = signatory.Signature(depth=3)
self.linear = nn.Linear(signatory.signature_channels(3, 3), 10)

def forward(self, x):
return self.linear(self.sig(x, basepoint=True))

model = SigNet()
compiled_model = torch.compile(model)
# Works! (with warnings about C++ extensions)
```

**Note**: You may see warnings from torch.compile about not being able to trace the C++ extensions. This is expected and does not affect functionality.

## Migration Checklist

If you're upgrading from Signatory 1.x to 2.0:

- [ ] Update Python to 3.10 or higher
- [ ] Update PyTorch to 2.x
- [ ] Reinstall Signatory 2.0
- [ ] Test your code (no API changes required!)
- [ ] Optionally try torch.compile for potential speedups

## Technical Details

### Fixed Issues

1. **GIL Handling in PyCapsule Creation**
- **Issue**: The `make_lyndon_info` function released the GIL before calling `wrap_capsule`, which internally calls `PyCapsule_New`. This Python C API function requires the GIL to be held.
- **Fix**: Scoped the GIL release to only cover the Lyndon computation, re-acquiring it before capsule creation.
- **Impact**: Prevents segmentation faults when using logsignature operations.

2. **Deprecated Tensor Creation**
- **Issue**: `torch.Tensor()` is deprecated in PyTorch 2.x
- **Fix**: Replaced with `torch.empty(0)` in `signature_module.py`
- **Impact**: Eliminates deprecation warnings and ensures future compatibility.

### Compatibility Matrix

| Signatory Version | Python Version | PyTorch Version |
|-------------------|----------------|-----------------|
| 2.0.0 | 3.10-3.12 | 2.x |
| 1.2.7 | 3.7-3.9 | 1.8.0-1.11.0 |

## Testing

All core functionality has been tested:
- ✅ Signature computation (CPU and CUDA)
- ✅ Logsignature computation (CPU and CUDA)
- ✅ All example scripts
- ✅ torch.compile integration
- ✅ Backwards pass and gradients

## Getting Help

If you encounter issues:
1. Check that you're using Python 3.10+ and PyTorch 2.x
2. Try installing from source if pre-built wheels don't work
3. Open an issue on GitHub with details about your environment

## Acknowledgments

This modernization effort was undertaken to ensure Signatory remains compatible with the latest PyTorch ecosystem and container environments like NVIDIA PyTorch containers.

71 changes: 52 additions & 19 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,48 @@ Check out `this <https://arxiv.org/abs/1603.03788>`__ for a primer on the use of
Installation
############

.. code-block:: bash
**Signatory 2.0 - PyTorch 2.x Support**

pip install signatory==<SIGNATORY_VERSION>.<TORCH_VERSION> --no-cache-dir --force-reinstall
Signatory 2.0 has been modernized for PyTorch 2.x with support for Python 3.10+.

where ``<SIGNATORY_VERSION>`` is the version of Signatory you would like to download (the most recent version is 1.2.7) and ``<TORCH_VERSION>`` is the version of PyTorch you are using.
Installation from source
------------------------

Available for Python 3.7--3.9 on Linux and Windows. Requires `PyTorch <http://pytorch.org/>`__ 1.8.0--1.11.0.
.. code-block:: bash

(If you need it, then previous versions of Signatory included support for older versions of Python, PyTorch, and MacOS, see `here <https://signatory.readthedocs.io/en/latest/pages/usage/installation.html#older-versions>`__.)
git clone https://github.com/patrick-kidger/signatory.git
cd signatory
git checkout pytorch-2.10-modernization
pip install -e . --no-build-isolation

After installation, just ``import signatory`` inside Python.
**Requirements:**

Take care **not** to run ``pip install signatory``, as this will likely download the wrong version.
* Python 3.10, 3.11, or 3.12
* PyTorch 2.x (tested with PyTorch 2.10)
* Linux or Windows
* CUDA support (optional, for GPU acceleration)

Example:
--------
After installation, just ``import signatory`` inside Python.

For example, if you are using PyTorch 1.11.0 and want Signatory 1.2.7, then you should run:
**Legacy Installation (PyTorch 1.x)**

For PyTorch 1.8.0--1.11.0, use Signatory 1.2.7:

.. code-block:: bash

pip install signatory==1.2.7.1.11.0 --no-cache-dir --force-reinstall

Why you need to specify all of this:
------------------------------------
pip install signatory==1.2.7.<TORCH_VERSION> --no-cache-dir --force-reinstall

Yes, this looks a bit odd. This is needed to work around `limitations of PyTorch <https://github.com/pytorch/pytorch/issues/28754>`__ and `pip <https://www.python.org/dev/peps/pep-0440/>`__.
where ``<TORCH_VERSION>`` is your PyTorch version (e.g., ``1.11.0``).

The ``--no-cache-dir --force-reinstall`` flags are because ``pip`` doesn't expect to need to care about versions quite as much as this, so it will sometimes erroneously use inappropriate caches if not told otherwise.
**What's New in 2.0:**

Installation from source is also possible; please consult the `documentation <https://signatory.readthedocs.io/en/latest/pages/usage/installation.html#usage-install-from-source>`__. This also includes information on how to run the tests and benchmarks.
* PyTorch 2.x compatibility
* Python 3.10+ support
* torch.compile support (with warnings for C++ extensions)
* Fixed GIL handling in PyCapsule creation
* Updated to modern PyTorch APIs

If you have any problems with installation then check the `FAQ <https://signatory.readthedocs.io/en/latest/pages/miscellaneous/faq.html#miscellaneous-faq-importing>`__. If that doesn't help then feel free to `open an issue <https://github.com/patrick-kidger/signatory/issues>`__.
If you have any problems with installation, feel free to `open an issue <https://github.com/patrick-kidger/signatory/issues>`__.



Expand All @@ -78,7 +87,31 @@ Usage is straightforward. As a simple example,
signature = signatory.signature(path, depth)
# signature is a PyTorch tensor

For further examples, see the `documentation <https://signatory.readthedocs.io/en/latest/pages/examples/examples.html>`__.
**PyTorch 2.x torch.compile Support**

Signatory 2.0 works with torch.compile:

.. code-block:: python

import signatory
import torch
from torch import nn

class SigNet(nn.Module):
def __init__(self, in_channels, out_dimension, sig_depth):
super().__init__()
self.signature = signatory.Signature(depth=sig_depth)
sig_channels = signatory.signature_channels(in_channels, sig_depth)
self.linear = nn.Linear(sig_channels, out_dimension)

def forward(self, path):
return self.linear(self.signature(path, basepoint=True))

model = SigNet(3, 5, 3)
compiled_model = torch.compile(model)
# Works! (with expected warnings about C++ extensions)

For further examples, see the `documentation <https://signatory.readthedocs.io/en/latest/pages/examples/examples.html>`__ or ``examples/example_torch_compile.py``.


Citation
Expand Down
94 changes: 94 additions & 0 deletions build.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
Using pip 25.3 from /usr/local/lib/python3.12/dist-packages/pip (python 3.12)
Obtaining file:///signatory
Checking if build backend supports build_editable: started
Running command Checking if build backend supports build_editable
Checking if build backend supports build_editable: finished with status 'done'
Preparing editable metadata (pyproject.toml): started
Running command Preparing editable metadata (pyproject.toml)
/usr/local/lib/python3.12/dist-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated.
!!

********************************************************************************
Please consider removing the following classifiers in favor of a SPDX license expression:

License :: OSI Approved :: Apache Software License

See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
********************************************************************************

!!
self._finalize_license_expression()
running dist_info
creating /tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info
writing /tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/PKG-INFO
writing dependency_links to /tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/dependency_links.txt
writing top-level names to /tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/top_level.txt
writing manifest file '/tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/SOURCES.txt'
reading manifest file '/tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
adding license file 'LICENSE'
writing manifest file '/tmp/pip-modern-metadata-wjlwrq1v/signatory.egg-info/SOURCES.txt'
creating '/tmp/pip-modern-metadata-wjlwrq1v/signatory-2.0.0.dist-info'
Preparing editable metadata (pyproject.toml): finished with status 'done'
Building wheels for collected packages: signatory
Building editable for signatory (pyproject.toml): started
Running command Building editable for signatory (pyproject.toml)
/usr/local/lib/python3.12/dist-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated.
!!

********************************************************************************
Please consider removing the following classifiers in favor of a SPDX license expression:

License :: OSI Approved :: Apache Software License

See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
********************************************************************************

!!
self._finalize_license_expression()
running editable_wheel
creating /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info
writing /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/PKG-INFO
writing dependency_links to /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/dependency_links.txt
writing top-level names to /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/top_level.txt
writing manifest file '/tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/SOURCES.txt'
reading manifest file '/tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
adding license file 'LICENSE'
writing manifest file '/tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory.egg-info/SOURCES.txt'
creating '/tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory-2.0.0.dist-info'
creating /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory-2.0.0.dist-info/WHEEL
running build_py
running build_ext
building '_impl' extension
creating /tmp/tmp0rwtze28.build-temp/src
[1/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/misc.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/misc.cpp -o /tmp/tmp0rwtze28.build-temp/src/misc.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
[2/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/logsignature.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/logsignature.cpp -o /tmp/tmp0rwtze28.build-temp/src/logsignature.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
[3/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/signature.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/signature.cpp -o /tmp/tmp0rwtze28.build-temp/src/signature.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
[4/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/lyndon.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/lyndon.cpp -o /tmp/tmp0rwtze28.build-temp/src/lyndon.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
[5/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/tensor_algebra_ops.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/tensor_algebra_ops.cpp -o /tmp/tmp0rwtze28.build-temp/src/tensor_algebra_ops.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
[6/6] c++ -MMD -MF /tmp/tmp0rwtze28.build-temp/src/pytorchbind.o.d -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -I/usr/local/lib/python3.12/dist-packages/torch/include -I/usr/local/lib/python3.12/dist-packages/torch/include/torch/csrc/api/include -I/usr/include/python3.12 -c -c /signatory/src/pytorchbind.cpp -o /tmp/tmp0rwtze28.build-temp/src/pytorchbind.o -fvisibility=hidden -fopenmp -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME=_impl -std=c++17
creating /tmp/tmp0y7er1d4.build-lib/signatory
x86_64-linux-gnu-g++ -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -shared -Wl,-O1 -Wl,-Bsymbolic-functions /tmp/tmp0rwtze28.build-temp/src/logsignature.o /tmp/tmp0rwtze28.build-temp/src/lyndon.o /tmp/tmp0rwtze28.build-temp/src/misc.o /tmp/tmp0rwtze28.build-temp/src/pytorchbind.o /tmp/tmp0rwtze28.build-temp/src/signature.o /tmp/tmp0rwtze28.build-temp/src/tensor_algebra_ops.o -L/usr/local/lib/python3.12/dist-packages/torch/lib -L/usr/lib/x86_64-linux-gnu -lc10 -ltorch -ltorch_cpu -ltorch_python -o /tmp/tmp0y7er1d4.build-lib/signatory/_impl.cpython-312-x86_64-linux-gnu.so
copying /tmp/tmp0y7er1d4.build-lib/signatory/_impl.cpython-312-x86_64-linux-gnu.so -> src/signatory

Editable install will be performed using .pth file to extend `sys.path` with:
['src']

Options like `package-data`, `include/exclude-package-data` or
`packages.find.exclude/include` may have no effect.

adding '__editable__.signatory-2.0.0.pth'
creating '/tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64/tmp1ep7niun/.tmp-7wc9hrdc/signatory-2.0.0-0.editable-cp312-cp312-linux_x86_64.whl' and adding '/tmp/tmp20vhtgousignatory-2.0.0-0.editable-cp312-cp312-linux_x86_64.whl' to it
adding 'signatory-2.0.0.dist-info/licenses/LICENSE'
adding 'signatory-2.0.0.dist-info/METADATA'
adding 'signatory-2.0.0.dist-info/WHEEL'
adding 'signatory-2.0.0.dist-info/top_level.txt'
adding 'signatory-2.0.0.dist-info/RECORD'
Building editable for signatory (pyproject.toml): finished with status 'done'
Created wheel for signatory: filename=signatory-2.0.0-0.editable-cp312-cp312-linux_x86_64.whl size=7762 sha256=ec1169dc05ebbe6efc71d4fabfd650e15c93d8a125c58458f4d5d9165b8860cb
Stored in directory: /tmp/pip-ephem-wheel-cache-mghouf2m/wheels/11/5f/c6/92329f69b0f67068704658b7361388800bc48c1396d5250d64
Successfully built signatory
Installing collected packages: signatory
Successfully installed signatory-2.0.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
Loading