Skip to content

Commit d386429

Browse files
authored
Merge branch 'main' into add-estimate-dual-cone-spherical-volume
2 parents b866269 + 2c8a3cb commit d386429

File tree

116 files changed

+2056
-787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+2056
-787
lines changed

.github/dependabot.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "monthly"
7+
commit-message:
8+
prefix: ""
9+
labels:
10+
- "cc: chore"
11+
12+
- package-ecosystem: "pre-commit"
13+
directory: "/"
14+
schedule:
15+
interval: "monthly"
16+
commit-message:
17+
prefix: ""
18+
labels:
19+
- "cc: chore"

.github/workflows/build-deploy-docs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
tags:
77
- 'v[0-9]*.[0-9]*.[0-9]*'
88

9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: false
12+
913
env:
1014
UV_NO_SYNC: 1
1115

.github/workflows/checks.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
schedule:
77
- cron: '41 16 * * *' # Every day at 16:41 UTC (to avoid high load at exact hour values).
88

9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
913
env:
1014
UV_NO_SYNC: 1
1115

@@ -56,7 +60,7 @@ jobs:
5660
PYTEST_TORCH_DTYPE: ${{ matrix.dtype || 'float32' }}
5761

5862
- name: Upload results to Codecov
59-
uses: codecov/codecov-action@v4
63+
uses: codecov/codecov-action@v5
6064
with:
6165
token: ${{ secrets.CODECOV_TOKEN }}
6266

@@ -85,7 +89,7 @@ jobs:
8589
runs-on: ubuntu-latest
8690
steps:
8791
- name: Checkout code
88-
uses: actions/checkout@v4
92+
uses: actions/checkout@v6
8993

9094
# This will restore the cache for the current commit if it exists, or the most recent lychee
9195
# cache otherwise (including those saved for the main branch). It will also save the cache for
@@ -94,7 +98,7 @@ jobs:
9498
# temporary (rate limiting, network issue, etc.), and we always want to retry those links
9599
# everytime this action is run.
96100
- name: Restore lychee cache
97-
uses: actions/cache@v4
101+
uses: actions/cache@v5
98102
with:
99103
path: .lycheecache
100104
key: cache-lychee-${{ github.sha }}
@@ -110,7 +114,7 @@ jobs:
110114
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
111115

112116
code-quality:
113-
name: Code quality (ty and ruff)
117+
name: Code quality (ty and pre-commit hooks)
114118
runs-on: ubuntu-latest
115119
steps:
116120
- name: Checkout repository
@@ -125,8 +129,8 @@ jobs:
125129
with:
126130
groups: check test plot
127131

132+
- name: Run pre-commit hooks
133+
run: uv run pre-commit run --all-files
134+
128135
- name: Run ty
129136
run: uv run ty check --output-format=github
130-
131-
- name: Run ruff
132-
run: uv run ruff check --output-format=github

.github/workflows/opencode.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: opencode
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
opencode:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '/opencode:')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '/opencode:')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '/opencode:')) ||
19+
(github.event_name == 'issues' && contains(github.event.issue.body, '/opencode:'))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
id-token: write
23+
contents: write
24+
pull-requests: write
25+
issues: write
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v6
29+
with:
30+
fetch-depth: 1
31+
persist-credentials: false
32+
33+
- name: Extract agent name
34+
id: agent
35+
env:
36+
COMMENT_BODY: ${{ github.event.comment.body || github.event.review.body || github.event.issue.body }}
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
run: |
39+
AGENT=$(echo "$COMMENT_BODY" | grep -oP '/opencode:\K[A-Za-z]+' | head -1)
40+
if [[ ! "$AGENT" =~ ^(Build|Plan)$ ]]; then
41+
ERROR_MSG="Error: Invalid agent '$AGENT'. Must be Build or Plan"
42+
echo "$ERROR_MSG"
43+
44+
# Post comment with error
45+
if [ "${{ github.event_name }}" = "issues" ]; then
46+
NUMBER=${{ github.event.issue.number }}
47+
else
48+
NUMBER=${{ github.event.issue.number || github.event.pull_request.number }}
49+
fi
50+
51+
curl -s -X POST \
52+
-H "Authorization: token $GITHUB_TOKEN" \
53+
-H "Accept: application/vnd.github.v3+json" \
54+
"https://api.github.com/repos/${{ github.repository }}/issues/$NUMBER/comments" \
55+
-d "{\"body\": \"❌ $ERROR_MSG\"}"
56+
57+
exit 1
58+
fi
59+
echo "agent=$AGENT" >> $GITHUB_OUTPUT
60+
61+
- name: Run opencode
62+
uses: anomalyco/opencode/github@latest
63+
env:
64+
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
65+
OPENCODE_PERMISSION: '{"bash": "deny"}'
66+
with:
67+
model: opencode-go/kimi-k2.5
68+
agent: ${{ steps.agent.outputs.agent }}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: PR Title Formatter
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, edited, reopened, labeled, unlabeled, synchronize]
6+
7+
jobs:
8+
format-title:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
pull-requests: write
12+
steps:
13+
- name: Format PR Title from Labels
14+
uses: actions/github-script@v8
15+
with:
16+
script: |
17+
const { owner, repo } = context.repo;
18+
const pr_number = context.payload.pull_request.number;
19+
const rawTitle = context.payload.pull_request.title;
20+
21+
const ccRegex = /^[a-z-]+(?:\([^)]+\))?!?: (.+)$/;
22+
const ccMatch = rawTitle.match(ccRegex);
23+
let description = ccMatch ? ccMatch[1] : rawTitle;
24+
25+
description = description.charAt(0).toUpperCase() + description.slice(1);
26+
27+
const prLabels = await github.rest.issues.listLabelsOnIssue({
28+
owner,
29+
repo,
30+
issue_number: pr_number,
31+
per_page: 100,
32+
});
33+
const labelNames = prLabels.data.map(l => l.name);
34+
35+
const ccLabels = labelNames.filter(n => n.startsWith('cc: '));
36+
if (ccLabels.length === 0) {
37+
core.setFailed('No "cc: <type>" label found on this PR. Please add exactly one.');
38+
return;
39+
}
40+
if (ccLabels.length > 1) {
41+
core.setFailed(`Multiple "cc: <type>" labels found: ${ccLabels.join(', ')}. Please keep exactly one.`);
42+
return;
43+
}
44+
const type = ccLabels[0].slice(4);
45+
46+
const packageLabels = labelNames.filter(n => n.startsWith('package: '));
47+
const scope = packageLabels.length === 1 ? packageLabels[0].slice(9) : null;
48+
49+
const isBreaking = labelNames.includes('breaking-change');
50+
51+
let newTitle = type;
52+
if (scope) newTitle += `(${scope})`;
53+
if (isBreaking) newTitle += '!';
54+
newTitle += `: ${description}`;
55+
56+
if (rawTitle === newTitle) {
57+
console.log("Title is already correctly formatted. Skipping update.");
58+
return;
59+
}
60+
61+
const displayTitle = `${newTitle} (#${pr_number})`;
62+
if (displayTitle.length > 72) {
63+
core.setFailed(
64+
`Formatted title is too long by ${displayTitle.length - 72} characters: "${displayTitle}"`
65+
);
66+
return;
67+
}
68+
69+
await github.rest.pulls.update({
70+
owner,
71+
repo,
72+
pull_number: pr_number,
73+
title: newTitle,
74+
});
75+
console.log(`PR title updated to: "${newTitle}"`);

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Claude (see https://github.com/anthropics/claude-code/issues/6235)
2+
CLAUDE.md
3+
14
# Profiling results
25
traces/
36

.pre-commit-config.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@ repos:
1010
- id: check-merge-conflict # Check for files that contain merge conflict strings.
1111

1212
- repo: https://github.com/astral-sh/ruff-pre-commit
13-
rev: v0.15.1
13+
rev: v0.15.5
1414
hooks:
1515
- id: ruff-check
1616
args: [ --fix, --ignore, FIX ] # Allow committing with TODOs. Only CI checks should prevent merging with TODOs.
1717
- id: ruff-format
18-
19-
ci:
20-
autoupdate_commit_msg: 'chore: Update pre-commit hooks'
21-
autoupdate_schedule: quarterly

CHANGELOG.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@ changelog does not include internal changes that do not affect the user.
88

99
## [Unreleased]
1010

11+
## [0.9.0] - 2026-02-24
12+
1113
### Added
1214

1315
- Added the function `torchjd.autojac.jac`. It's the same as `torchjd.autojac.backward` except that
1416
it returns the Jacobians as a tuple instead of storing them in the `.jac` fields of the inputs.
1517
Its interface is analog to that of `torch.autograd.grad`.
18+
- Added a `jac_tensors` parameter to `backward`, allowing to pre-multiply the Jacobian computation
19+
by initial Jacobians. This enables multi-step chain rule computations and is analogous to the
20+
`grad_tensors` parameter in `torch.autograd.backward`.
21+
- Added a `grad_tensors` parameter to `mtl_backward`, allowing to use non-scalar `losses` (now
22+
renamed to `tensors`). This is analogous to the `grad_tensors` parameter of
23+
`torch.autograd.backward`. When using `scalar` losses, the usage does not change.
24+
- Added a `jac_outputs` parameter to `jac`, allowing to pre-multiply the Jacobian computation by
25+
initial Jacobians. This is analogous to the `grad_outputs` parameter in `torch.autograd.grad`.
1626
- Added a `scale_mode` parameter to `AlignedMTL` and `AlignedMTLWeighting`, allowing to choose
1727
between `"min"`, `"median"`, and `"rmse"` scaling.
1828
- Added an attribute `gramian_weighting` to all aggregators that use a gramian-based `Weighting`.
@@ -45,11 +55,23 @@ changelog does not include internal changes that do not affect the user.
4555
mtl_backward(losses, features)
4656
jac_to_grad(shared_module.parameters(), aggregator)
4757
```
48-
49-
- Removed an unnecessary memory duplication. This should significantly improve the memory efficiency
50-
of `autojac`.
51-
- Removed an unnecessary internal cloning of gradient. This should slightly improve the memory
52-
efficiency of `autojac`.
58+
- **BREAKING**: Made some parameters of the public interface of `torchjd` positional-only or
59+
keyword-only:
60+
- `backward`: The `tensors` parameter is now positional-only. Suggested change:
61+
`backward(tensors=losses)` => `backward(losses)`. All other parameters are now keyword-only.
62+
- `mtl_backward`: The `tensors` parameter (previously named `losses`) is now positional-only.
63+
Suggested change: `mtl_backward(losses=losses, features=features)` =>
64+
`mtl_backward(losses, features=features)`. The `features` parameter remains usable as positional
65+
or keyword. All other parameters are now keyword-only.
66+
- `Aggregator.__call__`: The `matrix` parameter is now positonal-only. Suggested change:
67+
`aggregator(matrix=matrix)` => `aggregator(matrix)`.
68+
- `Weighting.__call__`: The `stat` parameter is now positional-only. Suggested change:
69+
`weighting(stat=gramian)` => `weighting(gramian)`.
70+
- `GeneralizedWeighting.__call__`: The `generalized_gramian` parameter is now positional-only.
71+
Suggested change: `generalized_weighting(generalized_gramian=generalized_gramian)` =>
72+
`generalized_weighting(generalized_gramian)`.
73+
- Removed several unnecessary memory duplications. This should significantly improve the memory
74+
efficiency and speed of `autojac`.
5375
- Increased the lower bounds of the torch (from 2.0.0 to 2.3.0) and numpy (from 1.21.0
5476
to 1.21.2) dependencies to reflect what really works with torchjd. We now also run torchjd's tests
5577
with the dependency lower-bounds specified in `pyproject.toml`, so we should now always accurately

CLAUDE.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)