class_docstr: A plain python object modeling a list of :class:`deepsnap.graph.Graph` 
  objects with various (optional) attributes.
  
  Args:
      graphs (list, optional): A list of :class:`deepsnap.graph.Graph`.
      task (str): The task that this :class:`GraphDataset` is used for
          (task = `node` or `edge` or `link_pred` or `graph`).
      custom_split_graphs (list): A list of 2 (train and val)
          or 3 (train, val and test) lists of splitted graphs, used in
          custom split of the `graph` task.
      edge_negative_sampling_ratio (float): The number of negative
          samples compared to that of positive edges. Default value 
          is 1.
      edge_message_ratio (float): The number of message passing edges
          compared to that of training supervision edges. Default value 
          is 0.8.
      edge_train_mode (str): Use `all` or `disjoint`. In `all` 
          mode, training supervision edges are same with the message 
          passing edges. In `disjoint` mode, training supervision 
          objectives are different from the message passing edges. 
          The difference between these two modes please see 
          the `DeepSNAP link prediction Colab <https://colab.research.
          google.com/drive/1ycdlJuse7l2De7wi51lFd_nCuaWgVABc?
          usp=sharing>`_.
      edge_split_mode (str): Use `exact` or `approximate`. This mode is 
          designed for the heterogeneous graph. If the mode is `exact`, 
          split the heterogeneous graph according to both the ratio
          and the split type. If the mode is `approximate`, split the 
          heterogeneous graph regardless of the split type.
      minimum_node_per_graph (int): If the number of nodes of a graph
          is smaller than the minimum node per graph, that graph will 
          be filtered out.
      generator (:class:`Generator`): The dataset will be on-the-fly 
          generated. The on-the-fly generator will be used, if the 
          :obj:`self.graphs` is empty or `None`, and the generator 
          (:class:`Generator`) is provided with an overwritten 
          :meth:`generate` method.
      resample_negatives (bool): Whether to resample negative edges in
          each iteration of the `link_pred` task. User needs to set this
          variable in the case of tensor backend for the custom split.
      resample_disjoint (bool): Whether to resample disjoint training 
          edges in the `disjonint` `link_pred` task.
      resample_disjoint_period (int): The number of iterations after
          which the training edges in the `disjoint` mode are resampled.
      negative_label_val (int, optional): The value of negative edges 
          generated in link_pred task. User needs to set this variable 
          in the case of tensor backend custom split.
      netlib (types.ModuleType, optional): The graph backend module. 
          Currently DeepSNAP supports the NetworkX and SnapX (for 
          SnapX only the undirected homogeneous graph) as the graph 
          backend. Default graph backend is the NetworkX.
class_docstr_tok: ["A","plain","python","object","modeling","a","list","of",":","class",":","`","deepsnap.graph.Graph","`","objects","with","various","(","optional",")","attributes",".","Args",":","graphs","(","list",",","optional",")",":","A","list","of",":","class",":","`","deepsnap.graph.Graph","`",".","task","(","str",")",":","The","task","that","this",":","class",":","`","GraphDataset","`","is","used","for","(","task","=","`","node","`","or","`","edge","`","or","`","link_pred","`","or","`","graph","`",")",".","custom_split_graphs","(","list",")",":","A","list","of","2","(","train","and","val",")","or","3","(","train",",","val","and","test",")","lists","of","splitted","graphs",",","used","in","custom","split","of","the","`","graph","`","task",".","edge_negative_sampling_ratio","(","float",")",":","The","number","of","negative","samples","compared","to","that","of","positive","edges",".","Default","value","is","1.","edge_message_ratio","(","float",")",":","The","number","of","message","passing","edges","compared","to","that","of","training","supervision","edges",".","Default","value","is","0.8.","edge_train_mode","(","str",")",":","Use","`","all","`","or","`","disjoint","`",".","In","`","all","`","mode",",","training","supervision","edges","are","same","with","the","message","passing","edges",".","In","`","disjoint","`","mode",",","training","supervision","objectives","are","different","from","the","message","passing","edges",".","The","difference","between","these","two","modes","please","see","the","`","DeepSNAP","link","prediction","Colab","<","https",":","\/\/colab.research",".","google.com\/drive\/1ycdlJuse7l2De7wi51lFd_nCuaWgVABc","?","usp=sharing",">","`","_",".","edge_split_mode","(","str",")",":","Use","`","exact","`","or","`","approximate","`",".","This","mode","is","designed","for","the","heterogeneous","graph",".","If","the","mode","is","`","exact","`",",","split","the","heterogeneous","graph","according","to","both","the","ratio","and","the","split","type",".","If","the","mode","is","`","approximate","`",",","split","the","heterogeneous","graph","regardless","of","the","split","type",".","minimum_node_per_graph","(","int",")",":","If","the","number","of","nodes","of","a","graph","is","smaller","than","the","minimum","node","per","graph",",","that","graph","will","be","filtered","out",".","generator","(",":","class",":","`","Generator","`",")",":","The","dataset","will","be","on-the-fly","generated",".","The","on-the-fly","generator","will","be","used",",","if","the",":","obj",":","`","self.graphs","`","is","empty","or","`","None","`",",","and","the","generator","(",":","class",":","`","Generator","`",")","is","provided","with","an","overwritten",":","meth",":","`","generate","`","method",".","resample_negatives","(","bool",")",":","Whether","to","resample","negative","edges","in","each","iteration","of","the","`","link_pred","`","task",".","User","needs","to","set","this","variable","in","the","case","of","tensor","backend","for","the","custom","split",".","resample_disjoint","(","bool",")",":","Whether","to","resample","disjoint","training","edges","in","the","`","disjonint","`","`","link_pred","`","task",".","resample_disjoint_period","(","int",")",":","The","number","of","iterations","after","which","the","training","edges","in","the","`","disjoint","`","mode","are","resampled",".","negative_label_val","(","int",",","optional",")",":","The","value","of","negative","edges","generated","in","link_pred","task",".","User","needs","to","set","this","variable","in","the","case","of","tensor","backend","custom","split",".","netlib","(","types.ModuleType",",","optional",")",":","The","graph","backend","module",".","Currently","DeepSNAP","supports","the","NetworkX","and","SnapX","(","for","SnapX","only","the","undirected","homogeneous","graph",")","as","the","graph","backend",".","Default","graph","backend","is","the","NetworkX","."]
code: def __init__(
      self,
      graphs: List[Graph] = None,
      task: str = "node",
      custom_split_graphs: List[Graph] = None,
      edge_negative_sampling_ratio: float = 1,
      edge_message_ratio: float = 0.8,
      edge_train_mode: str = "all",
      edge_split_mode: str = "exact",
      minimum_node_per_graph: int = 5,
      generator=None,
      resample_negatives: bool = False,
      resample_disjoint: bool = False,
      resample_disjoint_period: int = 1,
      negative_label_val: int = None,
      netlib=None,
  ):
      if netlib is not None:
          deepsnap._netlib = netlib
      if graphs is not None:
          # make sure graphs is a list
          if not isinstance(graphs, list):
              graphs = [graphs]
  
          # support user' input a list of netlib.Graph instead of Graph
          for i, graph in enumerate(graphs):
              if not isinstance(graph, Graph):
                  graphs[i] = Graph(graph, netlib=netlib)
  
      # validity check for `task`
      if task not in ["node", "edge", "link_pred", "graph"]:
          raise ValueError(
              "task must be one of node, edge, link_pred or graph."
          )
  
      # validity check for `edge_train_mode`
      if edge_train_mode not in ["all", "disjoint"]:
          raise ValueError("edge_train_mode must be all or disjoint.")
  
      # validity check for `edge_split_mode`
      if edge_split_mode not in ["exact", "approximate"]:
          raise ValueError(
              "edge_split_mode must be exact or approximate."
          )
  
      # validity check for `resample_negatives`
      if resample_negatives and (task != "link_pred"):
          raise ValueError(
              "resample_negatives set to True only make sense "
              "when self.task is link_pred."
          )
  
      # validity check for `resample_disjoint`
      # if resample_negatives and (self.task != "link_pred"):
      if resample_disjoint and (
          (task != "link_pred") or (edge_train_mode != "disjoint")
      ):
          raise ValueError(
              "resample_disjoint set to True only make sense "
              "when self.task is `link_pred` and edge_train_mode is "
              "disjoint."
          )
      # validity check for `resample_negatives`
      if (negative_label_val is not None) and (task != "link_pred"):
          raise ValueError(
              "negative_label_val is set only make sense "
              "when self.task is link_pred."
          )
  
      # parameter initialization
      self.graphs = graphs
      self.task = task
      self.custom_split_graphs = custom_split_graphs
      self.edge_message_ratio = edge_message_ratio
      self.edge_negative_sampling_ratio = edge_negative_sampling_ratio
      self.edge_train_mode = edge_train_mode
      self.edge_split_mode = edge_split_mode
      self.minimum_node_per_graph = minimum_node_per_graph
      self.resample_negatives = resample_negatives
      self.resample_disjoint = resample_disjoint
      self.resample_disjoint_period = resample_disjoint_period
      self.negative_label_val = negative_label_val
  
      # set private parameters
      self._split_types = None
      self._is_tensor = False
  
      # graphs preprocessing
      if graphs is None or len(graphs) == 0:
          if generator is None:
              raise ValueError("Graphs are None")
          else:
              # on-the-fly dataset
              self.generator = generator
              self.graphs = None
              self.otf_device = None
      elif generator is not None:
          raise ValueError(
              "Both graphs and on-the-fly generator are "
              "provided (only one should be provided."
          )
      else:
          # by default on-the-fly generator is not used
          # when generator is not provide
          self.generator = None
  
          # filter graphs that are too small
          if self.minimum_node_per_graph > 0:
              graphs_filter = []
              for idx, graph in enumerate(self.graphs):
                  if isinstance(graph, Graph):
                      if isinstance(graph, HeteroGraph):
                          if (
                              sum(graph.num_nodes().values())
                              >= self.minimum_node_per_graph
                          ):
                              graphs_filter.append(graph)
                          else:
                              warnings.warn(
                                  f"the {idx}-th graph in self.graphs is "
                                  "filtered out as it contains "
                                  f"{sum(graph.num_nodes().values())} nodes,"
                                  " which is less than "
                                  "self.minimum_node_per_graph: "
                                  f"{self.minimum_node_per_graph}."
                              )
                      else:
                          if (
                              graph.num_nodes
                              >= self.minimum_node_per_graph
                          ):
                              graphs_filter.append(graph)
                          else:
                              warnings.warn(
                                  f"the {idx}-th graph in self.graphs is "
                                  "filtered out as it contains "
                                  f"{graph.num_nodes} nodes,"
                                  " which is less than "
                                  "self.minimum_node_per_graph: "
                                  f"{self.minimum_node_per_graph}."
                              )
                  else:
                      raise TypeError(
                          "element in self.graphs of unexpected type"
                      )
              self.graphs = graphs_filter
  
          # update graph in self.graphs with appropriate custom
          # split component
          for graph in self.graphs:
              if not hasattr(graph, "_custom_update_flag"):
                  # assign task to graph
                  graph.task = self.task
  
                  # custom support
                  if isinstance(graph, Graph):
                      if isinstance(graph, HeteroGraph):
                          mapping = {
                              x: x
                              for x in range(
                                  sum(graph.num_nodes().values())
                              )
                          }
                      else:
                          mapping = {
                              x: x for x in range(graph.num_nodes)
                          }
                  else:
                      raise TypeError(
                          "element in self.graphs of unexpected type"
                      )
  
                  graph._custom_update(mapping)
  
          # update graph in self.graphs with negative_label_val
          if self.task == "link_pred":
              if self.negative_label_val is None:
                  negative_label_val = 0
                  for graph in self.graphs:
                      if (
                          hasattr(graph, "edge_label")
                          and (graph.edge_label is not None)
                          and (self.task == "link_pred")
                      ):
                          if isinstance(graph, Graph):
                              if isinstance(graph, HeteroGraph):
                                  for message_type in graph.edge_label:
                                      negative_label_val = max(
                                          negative_label_val,
                                          torch.max(
                                              graph.edge_label[
                                                  message_type
                                              ]
                                          ).item()
                                          + 1,
                                      )
                              else:
                                  negative_label_val = max(
                                      negative_label_val,
                                      torch.max(graph.edge_label).item()
                                      + 1,
                                  )
                          else:
                              raise TypeError(
                                  "element in self.graphs of unexpected type"
                              )
  
                  self.negative_label_val = negative_label_val
  
              for graph in self.graphs:
                  graph.negative_label_val = copy.deepcopy(
                      negative_label_val
                  )
  
          self._update_tensor_negative_edges()
          self._custom_mode_update()
      self._reset_cache()
  
imports: import copy
  import math
  import types
  import random
  import networkx
  import numpy
  import torch
  import deepsnap
  from deepsnap.graph import Graph
  from deepsnap.hetero_graph import HeteroGraph
  import pdb
  from typing import Dict, List, Union
  import warnings
label_desc: Use image node_id 1 to create a new GraphDataset object from inherited base classes: object with example: obj = GraphDataset(graphs, task, custom_split_graphs, edge_negative_sampling_ratio, edge_message_ratio, edge_train_mode, edge_split_mode, minimum_node_per_graph, generator, resample_negatives, resample_disjoint, resample_disjoint_period, negative_label_val, netlib)