code: def dropout_edge(
      edge_index: Tensor,
      p: float = 0.5,
      force_undirected: bool = False,
      training: bool = True,
  ) -> Tuple[Tensor, Tensor]:
      r"""Randomly drops edges from the adjacency matrix
      :obj:`edge_index` with probability :obj:`p` using samples from
      a Bernoulli distribution.
  
      The method returns (1) the retained :obj:`edge_index`, (2) the edge mask
      or index indicating which edges were retained, depending on the argument
      :obj:`force_undirected`.
  
      Args:
          edge_index (LongTensor): The edge indices.
          p (float, optional): Dropout probability. (default: :obj:`0.5`)
          force_undirected (bool, optional): If set to :obj:`True`, will either
              drop or keep both edges of an undirected edge.
              (default: :obj:`False`)
          training (bool, optional): If set to :obj:`False`, this operation is a
              no-op. (default: :obj:`True`)
  
      :rtype: (:class:`LongTensor`, :class:`BoolTensor` or :class:`LongTensor`)
  
      Examples:
          >>> edge_index = torch.tensor([[0, 1, 1, 2, 2, 3],
          ...                            [1, 0, 2, 1, 3, 2]])
          >>> edge_index, edge_mask = dropout_edge(edge_index)
          >>> edge_index
          tensor([[0, 1, 2, 2],
                  [1, 2, 1, 3]])
          >>> edge_mask # masks indicating which edges are retained
          tensor([ True, False,  True,  True,  True, False])
  
          >>> edge_index, edge_id = dropout_edge(edge_index,
          ...                                    force_undirected=True)
          >>> edge_index
          tensor([[0, 1, 2, 1, 2, 3],
                  [1, 2, 3, 0, 1, 2]])
          >>> edge_id # indices indicating which edges are retained
          tensor([0, 2, 4, 0, 2, 4])
      """
      if p < 0.0 or p > 1.0:
          raise ValueError(
              f"Dropout probability has to be between 0 and 1 "
              f"(got {p}"
          )
  
      if not training or p == 0.0:
          edge_mask = edge_index.new_ones(
              edge_index.size(1), dtype=torch.bool
          )
          return edge_index, edge_mask
  
      row, col = edge_index
  
      edge_mask = torch.rand(row.size(0), device=edge_index.device) >= p
  
      if force_undirected:
          edge_mask[row > col] = False
  
      edge_index = edge_index[:, edge_mask]
  
      if force_undirected:
          edge_index = torch.cat(
              [edge_index, edge_index.flip(0)], dim=1
          )
          edge_mask = edge_mask.nonzero().repeat((2, 1)).squeeze()
  
      return edge_index, edge_mask
  
file_path: pytorch_geometric/torch_geometric/utils/dropout.py
imports: from typing import Optional, Tuple
  import torch
  from torch import Tensor
  import torch_geometric.typing
  from torch_geometric import is_compiling
  from torch_geometric.deprecation import deprecated
  from torch_geometric.typing import OptTensor
  from torch_geometric.utils import cumsum, degree, sort_edge_index, subgraph
  from torch_geometric.utils.num_nodes import maybe_num_nodes
label_desc: Use image node_id 4 for calling a global function with example usage: dropout_edge(edge_index, p, force_undirected, training) and returns: edge_index,  edge_mask, edge_index,  edge_mask