Return a 1-D vector from torch.diagonal converter#2682
Conversation
`torch.diagonal(input, offset, dim1, dim2)` returns the requested
diagonal as a 1-D tensor (for 2-D input), but the converter used
`mb.band_part`, which only zeros the off-diagonal entries and returns
a same-shape matrix. As a result, `torch.diagonal(x)` for a 5x5 matrix
produced a 5x5 result instead of a length-5 vector.
Extract the diagonal by flattening the input and gathering the
elements at strides of `m + 1`, mirroring NumPy's row-major diagonal
indexing. Support `offset` and the `(dim1, dim2) == (1, 0)` transpose
case in addition to the default. Higher-rank input still raises
`NotImplementedError`, matching the pre-existing scope.
Verified end-to-end against PyTorch reference for shapes
{(5,5), (3,4), (4,3)}, offsets {-2,-1,0,1,2}, and dim swaps.
Fixes apple#2565.
e08d13d to
1ae5717
Compare
| raise NotImplementedError("diagonal requires a statically-shaped input") | ||
|
|
||
| if dim1 < 0: | ||
| dim1 += x.rank |
There was a problem hiding this comment.
I'm not sure the logic here is correct. It also looks like you don't have any unit test instances for when dim1 and dim2 are less than zero. Please add some.
|
Thanks for the review — addressed both points in Negative-dim tests added: the parametrize for On the logic concern (line 8381): the section is doing three things and I think the worry might be about the offset flip — happy to push a comment-only commit if anything below still reads ambiguously.
I cross-checked this against Re-running CI: https://gitlab.com/coremltools1/coremltools/-/pipelines/2534725082 covered the previous diff — pushed commit will need a fresh run. |
|
Thanks for the additional tests. Updated CI: https://gitlab.com/coremltools1/coremltools/-/pipelines/2538806799 If CI passes, this change should be good to merge. |
Summary
torch.diagonal(input, offset, dim1, dim2)returns the requested diagonal as a 1-D tensor (for 2-D input), but the converter usedmb.band_part, which only zeros the off-diagonal entries and returns the same-shape matrix. As a resulttorch.diagonal(x)for a 5x5 matrix produced a 5x5 result instead of a length-5 vector.m + 1, mirroring NumPy's row-major diagonal indexing.offsetand the(dim1, dim2) == (1, 0)transpose case in addition to the default(0, 1). Higher-rank input still raisesNotImplementedError, matching the pre-existing scope.Test plan
pytest test_torch_ops.py::TestDiagonal— 120 passed, 120 skipped (dim1==dim2 / empty-diagonal cases).Fixes #2565.