Repository navigation
Fix dense_to_sparse backward pass for three-dimensional input - #10758
JOhnsonKC201 wants to merge 3 commits into
Conversation
|
@akihironitta Gentle ping on this one and #10794: both still merge cleanly into master with pre-commit passing, but their Testing and Linting workflows are waiting on maintainer approval to run. Could you approve the workflows or take a look when you have a moment? |
|
@puririshi98 would you be able to take a look at this one? It fixes #10318 with a one-line change (the 3D branch of The Testing and Linting workflows have never run because they are waiting on approval for a first-time contributor, so approving them would be the first step. For context, #10842 was opened on 10-02 for the same issue with a similar fix. I'm happy for whichever one you prefer to go in. |
For 3D input, edge_attr is gathered with flatten_adj[edge_index[0], edge_index[1]], which saves those index tensors for the backward pass. The following line then shifted the column indices with an in-place +=, bumping their version counter, so calling backward on edge_attr raised a RuntimeError about a variable modified by an inplace operation. The 2D branch has no such mutation, which is why only 3D was affected. Build the shifted edge_index out-of-place instead. Forward output is unchanged for both the masked and unmasked paths.
d68e3f8 to
1f903ff
Compare
Fixes #10318.
Problem
dense_to_sparsebreaks autograd when the adjacency matrix is three-dimensional:The equivalent 2D call works fine, which is the clue.
Cause
In the 3D branch of
torch_geometric/utils/sparse.py:The advanced indexing on the second line saves
edge_index[0]andedge_index[1]for the index backward. The in-place+=then bumps theirversion counter, so autograd refuses to run backward. The 2D branch never
mutates
edge_index, which is exactly why only the 3D path is affected.Fix
Build the shifted
edge_indexout-of-place. One line, no API change, nobehavioural change.
I checked that the forward output is unchanged rather than assuming it: for a
seeded
3 x 4 x 4input, bothedge_indexandedge_attrare identical tomainon the unmasked path and on themask=path.Test plan
test_dense_to_sparse_backwardintest/utils/test_sparse.py,parametrised over
mask=Noneand a real mask. Both cases fail onmainwiththe
RuntimeErrorabove and pass with this change.pytest test/utils/test_sparse.py: 20 passed.flake8,isort --check-onlyandyapf --diffare clean on both changedfiles.