Fix backprop through cot_laplacian

Summary:
`_cot_laplacian_python` used in-place tensor operations (`clamp_`, `/=`,
`+=`) on intermediates that participate in autograd. Once the resulting
sparse Laplacian is used in a backward pass, these in-place mutations
raise a runtime error:

```
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.sparse.FloatTensor [4, 4]], which is output 0 of SparseCooTensorWithDimsAndTensors, is at version 1; expected version 0 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True, check_nan=False).
```

Replace the in-place ops with out-of-place equivalents so gradients can
flow back to the input vertices.

- `clamp_` → `clamp`
- `cot /= 4.0` → `cot = cot / 4.0`
- `L += L.t()` → `L = L + L.t()`

Reviewed By: bottler

Differential Revision: D111896032

fbshipit-source-id: 4c36677487bae5d37a9d81cb791400576f4b2c5f
This commit is contained in:
Roman Shapovalov
2026-07-14 12:07:08 -07:00
committed by meta-codesync[bot]
parent c8fcd83ff9
commit 3b5ab51de5
2 changed files with 15 additions and 4 deletions

View File

@@ -118,3 +118,14 @@ class TestLaplacianMatrices(TestCaseMixin, unittest.TestCase):
Lnaive[e1, e0] += w01
self.assertClose(L.to_dense(), Lnaive)
def test_cot_laplacian_backward(self):
"""Regression: in-place ops in _cot_laplacian_python break autograd."""
verts = torch.tensor(
[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]],
requires_grad=True,
)
faces = torch.tensor([[0, 1, 2], [1, 3, 2]])
L, inv_areas = cot_laplacian(verts, faces)
(L.to_dense().sum() + inv_areas.sum()).backward()
assert verts.grad is not None