This document explains how to contribute to TorchJD. Please use issues or discussions to communicate with maintainers before implementing major changes.
To work with TorchJD, we suggest you to use uv. While this is not
mandatory, we only provide installation steps with this tool. You can install it by following their
installation documentation. We also
suggest to use VSCode with the Python, ty and ruff extensions (without Pylance).
-
Pre-requisites: Use
uvto install a Python version compatible with TorchJD and to pin it to theTorchJDfolder. From the root of theTorchJDrepo, run:uv python install 3.14.0 uv python pin 3.14.0
-
Create a virtual environment and install the project in it. From the root of
TorchJD, run:uv venv CC=gcc uv pip install --python-version=3.14 -e '.[full]' --group check --group doc --group test --group plot
If you want to install PyTorch with a different CUDA version (this could be required depending on your GPU), you'll need to specify an extra index. For instance, for CUDA 12.6, run:
uv venv CC=gcc uv pip install --python-version=3.14 -e '.[full]' --group check --group doc --group test --group plot --index-strategy unsafe-best-match --extra-index-url https://download.pytorch.org/whl/cu126
-
Set environment variables:
We need to use
UV_NO_SYNC=1to preventuvfrom syncing all the time. This is because by default, it tries to resolve libraries compatible with the whole range of Python versions supported by TorchJD, but in reality, we just need an installation compatible with the currently used Python version. That's also why we specify--python-version=3.14when runninguv pip install. To follow that recommendation, add the following line to your.bashrc:export UV_NO_SYNC=1and start a new terminal. The alternative is to use the
--no-syncflag whenever you run a pip command that would normally sync (likeuv run).Lastly, to run some scripts from the
testsfolder, you'll have to add theTorchJD/testsfolder to yourPYTHONPATH. For that, you should add the following line to your.bashrc:export PYTHONPATH="$PYTHONPATH:<path_to_TorchJD>/tests"
where
<path_to_TorchJD>is the absolute path to yourTorchJDrepo. -
Install pre-commit:
uv run pre-commit install
Tip
If you're running into issues when uv tries to compile ecos, make sure that gcc is
installed. Alternatively, you can try to install clang or try to use some older Python version
(3.12) for which ecos has provided compiled packages (the list is accessible
here).
Tip
The Python version that you should specify in your IDE is <path-to-TorchJD>/.venv/bin/python.
Tip
In the following commands, you can get rid of the uv run prefix if you activate the venv
created by uv, using source .venv/bin/activate from the root of TorchJD. This will, however,
only work in the current terminal until it is closed.
If you want to update all dependencies or just reinstall from scratch, run the following command
from the root of TorchJD:
rm -rf .venv
rm -f uv.lock
uv venv
CC=gcc uv pip install --python-version=3.14 -e '.[full]' --group check --group doc --group test --group plot
uv run pre-commit install-
To verify that your installation was successful, and that unit tests pass, run:
uv run pytest tests/unit
-
To also run the unit tests that are marked as slow, add the
--runslowflag:uv run pytest tests/unit --runslow
-
If you have access to a cuda-enabled GPU, you should also check that the unit tests pass on it:
CUBLAS_WORKSPACE_CONFIG=:4096:8 PYTEST_TORCH_DEVICE=cuda:0 uv run pytest tests/unit
-
To check that the usage examples from docstrings and
.rstfiles are correct, we test their behavior intests/doc. To run these tests, do:uv run pytest tests/doc
-
To compute the code coverage locally, you should run the unit tests and the doc tests together, with the
--covflag:uv run pytest tests/unit tests/doc --cov=src
[!TIP] The code coverage value reported locally is lower than the value that our CI obtains, because the CI runs the tests in several different environments.
- From the
docsfolder, run:uv run make html
- You can then open
docs/build/html/index.htmlwith a web browser. - Sometimes, you need to manually delete the built documentation before generating it. To do
this, from the
docsfolder, run:uv run make clean
We use ty for type-checking. If you're on VSCode, we recommend using
the ty extension. You can also run it from the root of the repo with:
uv run ty checkThe following guidelines should help preserve a good code quality in TorchJD. Contributions that do not respect these guidelines will still be greatly appreciated but will require more work from maintainers to be merged.
Most source Python files in TorchJD have a corresponding .rst in docs/source. Please make sure
to add such a documentation entry whenever you add a new public module. In most cases, public
classes should contain a usage example in their docstring. We also ask contributors to add an entry
in the [Unreleased] section of the changelog whenever they make a change that may affect users (we
do not report internal changes). If this section does not exist yet (right after a release), you
should create it.
We ask contributors to implement the unit tests necessary to check the correctness of their
implementations. Besides, whenever usage examples are provided, we require the example's code to be
tested in tests/doc. We aim for 100% code coverage, but we greatly appreciate any PR, even with
insufficient code coverage. To ensure that the tensors generated during the tests are on the right
device and dtype, you have to use the partial functions defined in tests/utils/tensors.py to
instantiate tensors. For instance, instead of
import torch
a = torch.ones(3, 4)use
from utils.tensors import ones_
a = ones_(3, 4)This will automatically call torch.ones with device=DEVICE. This way, your test will
automatically be run on cuda when running it with the PYTEST_TORCH_DEVICE=cuda:0 environment
variable, and will automatically be run on float64 with PYTEST_TORCH_DTYPE=float64.
If the function you need does not exist yet as a partial function in tensors.py, add it.
Lastly, when you create a model or a random generator, you have to move them manually to the right
device (the DEVICE defined in settings.py).
import torch
from torch.nn import Linear
from settings import DEVICE
model = Linear(3, 4).to(device=DEVICE)
rng = torch.Generator(device=DEVICE)You may also use a ModuleFactory to make the modules on DEVICE automatically.
We try to keep the quality of the codebase as high as possible. Even if this slows down development
in the short term, it helps a lot in the long term. To make the code easy to understand and to
maintain, we try to keep it simple, and to stick as much as possible to the
SOLID principles. Try to preserve the existing coding style
of the library when adding new sources. Also, please make sure that new modules are imported by the
__init__.py file of the package they are located into. This makes them easier to import for the
user.
Mathematically, an aggregator is a mapping Aggregator subclass should be a faithful
implementation of a mathematical aggregator.
Warning
Currently, we only accept aggregators that have the same interface as the Aggregator base class.
We do not support stateful aggregators yet, so the proposed aggregators must be immutable.
Note
Before working on the implementation of a new aggregator, please contact us via an issue or a discussion: in many cases, we have already thought about it, or even started an implementation.
To deprecate some public functionality, make it raise a DeprecationWarning. A test should also be
added in tests/unit/test_deprecations.py, ensuring that this warning is issued.
This section is addressed to maintainers.
To release a new torchjd version, you have to:
- If the release introduces changes to the interface, make sure that
README.mdreflects those changes. - Make sure that all tests, including those on cuda, pass (for this, you need access to a machine that has a cuda-enabled GPU).
- Make sure that all important changes since the last release have been reported in the
[Unreleased]section at the top of the changelog. - Add a
[X.Y.Z] - yyyy-mm-ddheader in the changelog just below the[Unreleased]header. - Change the version in
pyproject.toml. - Make a pull request with those changes and merge it.
- Make a draft of the release on GitHub (click on
Releases, thenDraft a new release, then fill the details). - Publish the release (click on
Publish release). This should trigger the deployment of the new version on PyPI and the building and deployment of the documentation on github-pages. - Check that the new version is correctly deployed to PyPI, that it is installable and that it works.
- Check that the documentation has been correctly deployed.