CPU: _unique_cpu
CUDA: _unique_cuda
+- func: unique_dim(Tensor self, int dim, bool sorted=True, bool return_inverse=False, bool return_counts=False) -> (Tensor, Tensor, Tensor)
+ matches_jit_signature: True
+ variants: function
+ dispatch:
+ CPU: unique_dim_cpu
+ CUDA: unique_dim_cuda
+
+# _unique_dim is deprecated and will be removed in the future. Please use unique_dim
+
- func: _unique_dim(Tensor self, int dim, bool sorted=True, bool return_inverse=False) -> (Tensor, Tensor)
variants: function
dispatch:
CUDA: unique_dim_consecutive_cuda
# _unique and _unique_dim are fragile and modifying them easily cause internal break
-# below two operators are a temporary hack for adding return_counts support
+# the below operator is a temporary hack for adding return_counts support
# Please don't rely on these two operators, they will be removed soon
- func: _unique2_temporary_will_remove_soon(Tensor self, bool sorted=True, bool return_inverse=False, bool return_counts=False) -> (Tensor, Tensor, Tensor)
CPU: _unique2_cpu
CUDA: _unique2_cuda
-- func: unique_dim(Tensor self, int dim, bool sorted=True, bool return_inverse=False, bool return_counts=False) -> (Tensor, Tensor, Tensor)
- matches_jit_signature: True
- variants: function
- dispatch:
- CPU: unique_dim_cpu
- CUDA: unique_dim_cuda
-
- func: _unsafe_view(Tensor self, int[] size) -> Tensor
- func: unsqueeze(Tensor(a) self, int dim) -> Tensor(a)
def test_unique_dim(self):
self.assertFalse(hasattr(torch, 'unique_dim'))
- torch.unique_dim = torch._C._VariableFunctions.unique_dim
def run_test(dtype=torch.float, device=torch.device('cpu')):
x = torch.tensor([[[1., 1.],
self.assertEqual(expected_unique_dim0, x_unique)
self.assertEqual(expected_inverse_dim0, x_inverse)
- x_unique, _, x_counts = torch.unique_dim(
+ x_unique, x_counts = torch.unique(
x,
return_inverse=False,
return_counts=True,
self.assertEqual(expected_unique_dim0, x_unique)
self.assertEqual(expected_counts_dim0, x_counts)
- x_unique, x_inverse, x_counts = torch.unique_dim(
+ x_unique, x_inverse, x_counts = torch.unique(
x,
return_inverse=True,
return_counts=True,
self.assertEqual(expected_unique_dim1, x_unique)
self.assertEqual(expected_inverse_dim1, x_inverse)
- x_unique, _, x_counts = torch.unique_dim(
+ x_unique, x_counts = torch.unique(
x,
return_inverse=False,
return_counts=True,
self.assertEqual(expected_unique_dim1, x_unique)
self.assertEqual(expected_counts_dim1, x_counts)
- x_unique, x_inverse, x_counts = torch.unique_dim(
+ x_unique, x_inverse, x_counts = torch.unique(
x,
return_inverse=True,
return_counts=True,
self.assertEqual(expected_unique_dim2, x_unique)
self.assertEqual(expected_inverse_dim2, x_inverse)
- x_unique, _, x_counts = torch.unique_dim(
+ x_unique, x_counts = torch.unique(
x,
return_inverse=False,
return_counts=True,
self.assertEqual(expected_unique_dim2, x_unique)
self.assertEqual(expected_counts_dim2, x_counts)
- x_unique, x_inverse, x_counts = torch.unique_dim(
+ x_unique, x_inverse, x_counts = torch.unique(
x,
return_inverse=True,
return_counts=True,
del torch.unique_dim
-def unique(input, sorted=True, return_inverse=False, dim=None):
- r"""Returns the unique scalar elements of the input tensor as a 1-D tensor.
+def unique(input, sorted=True, return_inverse=False, return_counts=False, dim=None):
+ r"""Returns the unique elements of the input tensor.
Arguments:
input (Tensor): the input tensor
before returning as output.
return_inverse (bool): Whether to also return the indices for where
elements in the original input ended up in the returned unique list.
+ return_counts (bool): Whether to also return the counts for each unique
+ element. Currently only supported when `dim` is not None.
dim (int): the dimension to apply unique. If ``None``, the unique of the
flattened input is returned. default: ``None``
Returns:
- (Tensor, Tensor (optional)): A tensor or a tuple of tensors containing
+ (Tensor, Tensor (optional) Tensor (optional))::
+ A tensor or a tuple of tensors containing
- **output** (*Tensor*): the output list of unique scalar elements.
- **inverse_indices** (*Tensor*): (optional) if
- :attr:`return_inverse` is True, there will be a
- 2nd returned tensor (same shape as input) representing the indices
+ :attr:`return_inverse` is True, there will be an additional
+ returned tensor (same shape as input) representing the indices
for where elements in the original input map to in the output;
otherwise, this function will only return a single tensor.
+ - **counts** (*Tensor*): (optional) if
+ :attr:`return_counts` is True, there will be an additional
+ returned tensor (same shape as output or output.size(dim),
+ if dim was specified) representing the number of occurrences
+ for each unique value or tensor.
Example::
"""
if dim is not None:
- output, inverse_indices = torch._unique_dim(
+ output, inverse_indices, counts = torch._C._VariableFunctions.unique_dim(
input,
dim,
sorted=sorted,
- return_inverse=return_inverse
+ return_inverse=return_inverse,
+ return_counts=return_counts,
)
else:
+ if return_counts:
+ raise NotImplementedError(
+ "torch.unique currently does not support return_counts with dim not None")
output, inverse_indices = torch._unique(
input,
sorted=sorted,
- return_inverse=return_inverse,
+ return_inverse=return_inverse
)
- if return_inverse:
+ if return_inverse and return_counts:
+ return output, inverse_indices, counts
+ elif return_inverse:
return output, inverse_indices
+ elif return_counts:
+ return output, counts
else:
return output
else:
return super(Tensor, self).split_with_sizes(split_size, dim)
- def unique(self, sorted=True, return_inverse=False, dim=None):
- r"""Returns the unique scalar elements of the tensor as a 1-D tensor.
+ def unique(self, sorted=True, return_inverse=False, return_counts=False, dim=None):
+ r"""Returns the unique elements of the input tensor.
See :func:`torch.unique`
"""
- if dim is not None:
- output, inverse_indices = torch._unique_dim(
- self,
- sorted=sorted,
- return_inverse=return_inverse,
- dim=dim
- )
- else:
- output, inverse_indices = torch._unique(
- self,
- sorted=sorted,
- return_inverse=return_inverse
- )
- if return_inverse:
- return output, inverse_indices
- else:
- return output
+ return torch.unique(self, sorted=sorted, return_inverse=return_inverse, return_counts=return_counts, dim=dim)
def unique_consecutive(self, return_inverse=False, return_counts=False, dim=None):
r"""Eliminates all but the first element from every consecutive group of equivalent elements.