class_docstr: The GraphSAINT sampler base class from the `"GraphSAINT: Graph
  Sampling Based Inductive Learning Method"
  <https://arxiv.org/abs/1907.04931>`_ paper.
  Given a graph in a :obj:`data` object, this class samples nodes and
  constructs subgraphs that can be processed in a mini-batch fashion.
  Normalization coefficients for each mini-batch are given via
  :obj:`node_norm` and :obj:`edge_norm` data attributes.
  
  .. note::
  
      See :class:`~torch_geometric.loader.GraphSAINTNodeSampler`,
      :class:`~torch_geometric.loader.GraphSAINTEdgeSampler` and
      :class:`~torch_geometric.loader.GraphSAINTRandomWalkSampler` for
      currently supported samplers.
      For an example of using GraphSAINT sampling, see
      `examples/graph_saint.py <https://github.com/pyg-team/
      pytorch_geometric/blob/master/examples/graph_saint.py>`_.
  
  Args:
      data (torch_geometric.data.Data): The graph data object.
      batch_size (int): The approximate number of samples per batch.
      num_steps (int, optional): The number of iterations per epoch.
          (default: :obj:`1`)
      sample_coverage (int): How many samples per node should be used to
          compute normalization statistics. (default: :obj:`0`)
      save_dir (str, optional): If set, will save normalization statistics to
          the :obj:`save_dir` directory for faster re-use.
          (default: :obj:`None`)
      log (bool, optional): If set to :obj:`False`, will not log any
          pre-processing progress. (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch.utils.data.DataLoader`, such as :obj:`batch_size` or
          :obj:`num_workers`.
code: def __init__(
      self,
      data,
      batch_size: int,
      num_steps: int = 1,
      sample_coverage: int = 0,
      save_dir: Optional[str] = None,
      log: bool = True,
      **kwargs,
  ):
      # Remove for PyTorch Lightning:
      kwargs.pop("dataset", None)
      kwargs.pop("collate_fn", None)
  
      assert data.edge_index is not None
      assert "node_norm" not in data
      assert "edge_norm" not in data
      assert not data.edge_index.is_cuda
  
      self.num_steps = num_steps
      self._batch_size = batch_size
      self.sample_coverage = sample_coverage
      self.save_dir = save_dir
      self.log = log
  
      self.N = N = data.num_nodes
      self.E = data.num_edges
  
      self.adj = SparseTensor(
          row=data.edge_index[0],
          col=data.edge_index[1],
          value=torch.arange(self.E, device=data.edge_index.device),
          sparse_sizes=(N, N),
      )
  
      self.data = data
  
      super().__init__(
          self, batch_size=1, collate_fn=self._collate, **kwargs
      )
  
      if self.sample_coverage > 0:
          path = osp.join(save_dir or "", self._filename)
          if save_dir is not None and osp.exists(
              path
          ):  # pragma: no cover
              self.node_norm, self.edge_norm = torch.load(path)
          else:
              self.node_norm, self.edge_norm = self._compute_norm()
              if save_dir is not None:  # pragma: no cover
                  torch.save((self.node_norm, self.edge_norm), path)
  
imports: import os.path
  from typing import Optional
  import torch
  from tqdm import tqdm
  from torch_geometric.typing import SparseTensor
label_desc: Use image node_id 1 to create a new GraphSAINTSampler object from inherited base classes: torch.utils.data with example: obj = GraphSAINTSampler(data, batch_size, num_steps, sample_coverage, save_dir, log)