code: def k_hop_subgraph_with_default_whole_graph(
      edge_index,
      node_idx=None,
      num_hops=3,
      relabel_nodes=False,
      num_nodes=None,
      flow="source_to_target",
  ):
      r"""Computes the :math:`k`-hop subgraph of :obj:`edge_index` around node
      :attr:`node_idx`.
      It returns (1) the nodes involved in the subgraph, (2) the filtered
      :obj:`edge_index` connectivity, (3) the mapping from node indices in
      :obj:`node_idx` to their new location, and (4) the edge mask indicating
      which edges were preserved.
      Args:
          node_idx (int, list, tuple or :obj:`torch.Tensor`): The central
              node(s).
          num_hops: (int): The number of hops :math:`k`.
          edge_index (LongTensor): The edge indices.
          relabel_nodes (bool, optional): If set to :obj:`True`, the resulting
              :obj:`edge_index` will be relabeled to hold consecutive indices
              starting from zero. (default: :obj:`False`)
          num_nodes (int, optional): The number of nodes, *i.e.*
              :obj:`max_val + 1` of :attr:`edge_index`. (default: :obj:`None`)
          flow (string, optional): The flow direction of :math:`k`-hop
              aggregation (:obj:`"source_to_target"` or
              :obj:`"target_to_source"`). (default: :obj:`"source_to_target"`)
      :rtype: (:class:`LongTensor`, :class:`LongTensor`, :class:`LongTensor`,
               :class:`BoolTensor`)
      """
  
      num_nodes = maybe_num_nodes(edge_index, num_nodes)
  
      assert flow in ["source_to_target", "target_to_source"]
      if flow == "target_to_source":
          row, col = edge_index
      else:
          (
              col,
              row,
          ) = edge_index  # edge_index 0 to 1, col: source, row: target
  
      node_mask = row.new_empty(num_nodes, dtype=torch.bool)
      edge_mask = row.new_empty(row.size(0), dtype=torch.bool)
  
      inv = None
  
      if node_idx is None:
          subsets = torch.tensor([0])
          cur_subsets = subsets
          while 1:
              node_mask.fill_(False)
              node_mask[subsets] = True
              torch.index_select(node_mask, 0, row, out=edge_mask)
              subsets = torch.cat([subsets, col[edge_mask]]).unique()
              if not cur_subsets.equal(subsets):
                  cur_subsets = subsets
              else:
                  subset = subsets
                  break
      else:
          if isinstance(node_idx, (int, list, tuple)):
              node_idx = torch.tensor(
                  [node_idx], device=row.device, dtype=torch.int64
              ).flatten()
          elif (
              isinstance(node_idx, torch.Tensor)
              and len(node_idx.shape) == 0
          ):
              node_idx = torch.tensor([node_idx])
          else:
              node_idx = node_idx.to(row.device)
  
          subsets = [node_idx]
          for _ in range(num_hops):
              node_mask.fill_(False)
              node_mask[subsets[-1]] = True
              torch.index_select(node_mask, 0, row, out=edge_mask)
              subsets.append(col[edge_mask])
          subset, inv = torch.cat(subsets).unique(return_inverse=True)
          inv = inv[: node_idx.numel()]
  
      node_mask.fill_(False)
      node_mask[subset] = True
      edge_mask = node_mask[row] & node_mask[col]
  
      edge_index = edge_index[:, edge_mask]
  
      if relabel_nodes:
          node_idx = row.new_full((num_nodes,), -1)
          node_idx[subset] = torch.arange(
              subset.size(0), device=row.device
          )
          edge_index = node_idx[edge_index]
  
      return subset, edge_index, inv, edge_mask
  
imports: import os
  import math
  import copy
  import torch
  import numpy
  import networkx
  from rdkit import Chem
  from torch import Tensor
  from textwrap import wrap
  from functools import partial
  from collections import Counter
  from typing import List, Tuple, Dict
  from torch_geometric.data import Batch, Data
  from torch_geometric.utils import to_networkx
  from typing import Callable, Union, Optional
  import matplotlib.pyplot
  from torch_geometric.utils.num_nodes import maybe_num_nodes
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.datasets import MoleculeNet
  from torch_geometric.utils import remove_self_loops
  from .shapley import GnnNetsGC2valueFunc, GnnNetsNC2valueFunc, gnn_score, mc_shapley, l_shapley, mc_l_shapley, NC_mc_l_shapley, sparsity
label_desc: Use image node_id 3 for calling a global function with example usage: k_hop_subgraph_with_default_whole_graph(edge_index, node_idx, num_hops, relabel_nodes, num_nodes, flow) and returns: subset,  edge_index,  inv,  edge_mask