code: def __coalesce(
      edge_index: torch.Tensor,
      edge_attr: _typing.Union[
          torch.Tensor, _typing.Iterable[torch.Tensor], None
      ] = None,
      num_nodes: _typing.Optional[int] = ...,
      is_sorted: bool = False,
      sort_by_row: bool = True,
  ) -> _typing.Union[
      torch.Tensor,
      _typing.Tuple[torch.Tensor, torch.Tensor],
      _typing.Tuple[torch.Tensor, _typing.Iterable[torch.Tensor]],
  ]:
      """
      Row-wise sorts :obj:`edge_index` and removes its duplicated entries.
      Duplicate entries in :obj:`edge_attr` are directly removed, instead of merged.
      Args:
          edge_index (LongTensor): The edge indices.
          edge_attr (Tensor or List[Tensor], optional): Edge weights or multi-
              dimensional edge features.
              If given as a list, will re-shuffle and remove duplicates for all
              its entries. (default: :obj:`None`)
          num_nodes (int, optional): The number of nodes, *i.e.*
              :obj:`max_val + 1` of :attr:`edge_index`. (default: :obj:`None`)
          is_sorted (bool, optional): If set to :obj:`True`, will expect
              :obj:`edge_index` to be already sorted row-wise.
          sort_by_row (bool, optional): If set to :obj:`False`, will sort
              :obj:`edge_index` column-wise.
      :rtype: :class:`LongTensor` if :attr:`edge_attr` is :obj:`None`, else
          (:class:`LongTensor`, :obj:`Tensor` or :obj:`Iterable[Tensor]]`)
      """
  
      if edge_attr is None:
          pass
      elif isinstance(edge_attr, torch.Tensor) and torch.is_tensor(
          edge_attr
      ):
          if edge_attr.size(0) != edge_index.size(1):
              raise ValueError
      elif isinstance(edge_attr, _typing.Iterable):
          if not all(
              [
                  (
                      isinstance(attr, torch.Tensor)
                      and attr.size(0) == edge_index.size(1)
                  )
                  for attr in edge_attr
              ]
          ):
              raise ValueError("Invalid edge_attr argument")
      else:
          raise TypeError("Unsupported type of edge_attr argument")
  
      nnz = edge_index.size(1)
      num_nodes = _maybe_num_nodes(edge_index, num_nodes)
  
      idx = edge_index.new_empty(nnz + 1)
      idx[0] = -1
      idx[1:] = edge_index[1 - int(sort_by_row)]
      idx[1:].mul_(num_nodes).add_(edge_index[int(sort_by_row)])
  
      if not is_sorted:
          idx[1:], perm = idx[1:].sort()
          edge_index = edge_index[:, perm]
          if edge_attr is not None and isinstance(
              edge_attr, torch.Tensor
          ):
              edge_attr = edge_attr[perm]
          elif edge_attr is not None:
              edge_attr = [e[perm] for e in edge_attr]
  
      mask: _typing.Any = idx[1:] > idx[:-1]
  
      # Only perform expensive merging in case there exists duplicates:
      if mask.all():
          return (
              edge_index
              if edge_attr is None
              else (edge_index, edge_attr)
          )
  
      edge_index = edge_index[:, mask]
      if edge_attr is None:
          return edge_index
      elif isinstance(edge_attr, torch.Tensor):
          return edge_index, edge_attr[mask]
      elif isinstance(edge_attr, _typing.Iterable):
          return edge_index, [attr[mask] for attr in edge_attr]
  
file_path: AutoGL/autogl/datasets/utils/_split_edges/train_test_split_edges.py
imports: import math
  import torch
  import typing
label_desc: Use image node_id 2 for calling a global function with example usage: __coalesce(edge_index, edge_attr, num_nodes, is_sorted, sort_by_row) and returns: unknown, edge_index, edge_index,  edge_attr, edge_index,  unknown