Skip to content

Commit ab099a2

Browse files
authored
refactor(linalg): Make Matrix and PSDMatrix public (#673)
- Introduces a new public `torchjd.linalg` package exposing `Matrix` and `PSDMatrix` (the rest of `_linalg` stays protected) - Makes `MatrixWeighting` and `GramianWeighting` protected. These classes are still used to specify the docstring of the `__call__` methods of the aggregators, but the user only sees those aggregators as `Weighting[Matrix]` and `Weighting[PSDMatrix]`, respectively. The `MatrixWeighting` and `GramianWeighting` classes really just bring updated docstrings, that's all. - Makes the public type of the gramian_weighting of GramianWeightedAggregator be Weighting[PSDMatrix] instead of GramianWeighting, so that #669 can work. Similar with weighting of WeightedAggregator being Weighting[Matrix]. - Expands docstrings on `Matrix` and `PSDMatrix` with Jacobian and Gramian examples; adds Sphinx documentation under a new **linalg** section in the API Reference
1 parent 2b13464 commit ab099a2

33 files changed

Lines changed: 169 additions & 125 deletions

CHANGELOG.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ changelog does not include internal changes that do not affect the user.
1010

1111
### Added
1212

13-
- Made `WeightedAggregator`, `GramianWeightedAggregator`, `MatrixWeighting`, and `GramianWeighting`
14-
public. These abstract base classes are now importable from `torchjd.aggregation` and documented.
15-
They can be extended to easily implement custom `Weighting`s and `Aggregator`s.
13+
- Made `WeightedAggregator` and `GramianWeightedAggregator` public. These abstract base classes are
14+
now importable from `torchjd.aggregation` and documented. They can be extended to easily implement
15+
custom `Aggregator`s.
16+
- Made `Matrix` and `PSDMatrix` public. These type annotation classes are now importable from
17+
`torchjd.linalg` and documented. Users can now subclass `Weighting[Matrix]` or
18+
`Weighting[PSDMatrix]` to implement custom `Weighting`s.
1619
- Added getters and setters for the constructor parameters of all aggregators and weightings, so
1720
that they can be changed after initialization. This includes: `pref_vector`,
1821
`norm_eps` and `reg_eps` in `UPGrad`, `UPGradWeighting`, `DualProj` and `DualProjWeighting`;

docs/source/docs/aggregation/index.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ Abstract base classes
1919
.. autoclass:: torchjd.aggregation.Weighting
2020
:members: __call__
2121

22-
.. autoclass:: torchjd.aggregation.MatrixWeighting
23-
:members: __call__
24-
25-
.. autoclass:: torchjd.aggregation.GramianWeighting
26-
:members: __call__
27-
2822
.. autoclass:: torchjd.aggregation.GeneralizedWeighting
2923
:members: __call__
3024

docs/source/docs/linalg/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
linalg
2+
======
3+
4+
.. automodule:: torchjd.linalg
5+
:no-members:
6+
7+
.. toctree::
8+
:hidden:
9+
:maxdepth: 1
10+
11+
matrix.rst
12+
psd_matrix.rst

docs/source/docs/linalg/matrix.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:hide-toc:
2+
3+
Matrix
4+
======
5+
6+
.. autoclass:: torchjd.linalg.Matrix
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:hide-toc:
2+
3+
PSDMatrix
4+
=========
5+
6+
.. autoclass:: torchjd.linalg.PSDMatrix

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ TorchJD is open-source, under MIT License. The source code is available on
7070
docs/autogram/index.rst
7171
docs/autojac/index.rst
7272
docs/aggregation/index.rst
73+
docs/linalg/index.rst

src/torchjd/_linalg/_matrix.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88

99

1010
class Matrix(Tensor):
11-
"""Tensor with exactly 2 dimensions."""
11+
"""
12+
Tensor with exactly 2 dimensions.
13+
14+
Common examples include the Jacobian matrix J of shape ``[m, n]``, where m is the number of
15+
objectives and n is the number of model parameters, and the Gramian of the Jacobian
16+
G = J J^T of shape ``[m, m]``.
17+
18+
.. note::
19+
This class should never be instantiated. It is only used for static type checking.
20+
"""
1221

1322

1423
class PSDTensor(Tensor):
@@ -20,7 +29,15 @@ class PSDTensor(Tensor):
2029

2130

2231
class PSDMatrix(PSDTensor, Matrix):
23-
"""Positive semi-definite matrix."""
32+
"""
33+
Positive semi-definite matrix.
34+
35+
A common example is the Gramian of the Jacobian G = J J^T of shape ``[m, m]``, where J is a
36+
Jacobian matrix of shape ``[m, n]``.
37+
38+
.. note::
39+
This class should never be instantiated. It is only used for static type checking.
40+
"""
2441

2542

2643
def is_matrix(t: Tensor) -> TypeGuard[Matrix]:

src/torchjd/aggregation/__init__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
1010
.. note::
1111
Most aggregators rely on computing the Gramian of the Jacobian, extracting a vector of weights
12-
from this Gramian using a :class:`~torchjd.aggregation.GramianWeighting`, and then combining the
13-
rows of the Jacobian using these weights. For all of them, we provide both the
12+
from this Gramian using a :class:`~torchjd.aggregation.Weighting`
13+
[:class:`~torchjd.linalg.PSDMatrix`], and then combining the rows of the Jacobian using these
14+
weights. For all of them, we provide both the
1415
:class:`~torchjd.aggregation.Aggregator` interface (to be used in autojac) and the
1516
:class:`~torchjd.aggregation.Weighting` interface (to be used in autogram).
1617
For the rest, we only provide the :class:`~torchjd.aggregation.Aggregator`
@@ -80,7 +81,7 @@
8081
from ._utils.check_dependencies import (
8182
OptionalDepsNotInstalledError as _OptionalDepsNotInstalledError,
8283
)
83-
from ._weighting_bases import GeneralizedWeighting, GramianWeighting, MatrixWeighting, Weighting
84+
from ._weighting_bases import GeneralizedWeighting, Weighting
8485

8586
__all__ = [
8687
"Aggregator",
@@ -97,12 +98,10 @@
9798
"GradVac",
9899
"GradVacWeighting",
99100
"GramianWeightedAggregator",
100-
"GramianWeighting",
101101
"IMTLG",
102102
"IMTLGWeighting",
103103
"Krum",
104104
"KrumWeighting",
105-
"MatrixWeighting",
106105
"Mean",
107106
"MeanWeighting",
108107
"MGDA",

src/torchjd/aggregation/_aggregator_bases.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from abc import ABC, abstractmethod
2-
from typing import cast
32

43
from torch import Tensor, nn
54

6-
from torchjd._linalg import Matrix, compute_gramian, is_matrix
5+
from torchjd._linalg import compute_gramian, is_matrix
6+
from torchjd.linalg import Matrix, PSDMatrix
77

8-
from ._weighting_bases import GramianWeighting, MatrixWeighting
8+
from ._weighting_bases import Weighting
99

1010

1111
class Aggregator(nn.Module, ABC):
@@ -48,12 +48,12 @@ def __str__(self) -> str:
4848
class WeightedAggregator(Aggregator):
4949
"""
5050
Aggregator that combines the rows of the input Jacobian matrix with weights given by applying a
51-
:class:`~torchjd.aggregation.MatrixWeighting` to it.
51+
:class:`~torchjd.aggregation.Weighting` [:class:`~torchjd.linalg.Matrix`] to it.
5252
5353
:param weighting: The object responsible for extracting the vector of weights from the matrix.
5454
"""
5555

56-
def __init__(self, weighting: MatrixWeighting) -> None:
56+
def __init__(self, weighting: Weighting[Matrix]) -> None:
5757
super().__init__()
5858
self.weighting = weighting
5959

@@ -76,12 +76,13 @@ def forward(self, matrix: Matrix, /) -> Tensor:
7676
class GramianWeightedAggregator(WeightedAggregator):
7777
"""
7878
:class:`~torchjd.aggregation.WeightedAggregator` that computes the gramian of the input
79-
Jacobian matrix before applying a :class:`~torchjd.aggregation.GramianWeighting` to it.
79+
Jacobian matrix before applying a :class:`~torchjd.aggregation.Weighting`
80+
[:class:`~torchjd.linalg.PSDMatrix`] to it.
8081
8182
:param gramian_weighting: The object responsible for extracting the vector of weights from the
8283
gramian.
8384
"""
8485

85-
def __init__(self, gramian_weighting: GramianWeighting) -> None:
86-
super().__init__(cast(MatrixWeighting, gramian_weighting << compute_gramian))
86+
def __init__(self, gramian_weighting: Weighting[PSDMatrix]) -> None:
87+
super().__init__(gramian_weighting << compute_gramian)
8788
self.gramian_weighting = gramian_weighting

src/torchjd/aggregation/_aligned_mtl.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@
77
import torch
88
from torch import Tensor
99

10-
from torchjd._linalg import PSDMatrix
10+
from torchjd.linalg import PSDMatrix
1111

1212
from ._aggregator_bases import GramianWeightedAggregator
1313
from ._mean import MeanWeighting
1414
from ._utils.pref_vector import pref_vector_to_str_suffix, pref_vector_to_weighting
15-
from ._weighting_bases import GramianWeighting
15+
from ._weighting_bases import _GramianWeighting
1616

1717
SUPPORTED_SCALE_MODE: TypeAlias = Literal["min", "median", "rmse"]
1818

1919

20-
class AlignedMTLWeighting(GramianWeighting):
20+
class AlignedMTLWeighting(_GramianWeighting):
2121
r"""
22-
:class:`~torchjd.aggregation.GramianWeighting` giving the weights of
23-
:class:`~torchjd.aggregation.AlignedMTL`.
22+
:class:`~torchjd.aggregation.Weighting` [:class:`~torchjd.linalg.PSDMatrix`]
23+
giving the weights of :class:`~torchjd.aggregation.AlignedMTL`.
2424
2525
:param pref_vector: The preference vector to use. If not provided, defaults to
2626
:math:`\begin{bmatrix} \frac{1}{m} & \dots & \frac{1}{m} \end{bmatrix}^T \in \mathbb{R}^m`.

0 commit comments

Comments
 (0)