class_docstr: Auto Multi-class Graph Node Classifier.
  
  Used to automatically solve the node classification problems.
  
  Parameters
  ----------
  feature_module: autogl.module.feature.BaseFeatureEngineer or str or None
      The (name of) auto feature engineer used to process the given dataset. Default ``deepgl``.
      Disable feature engineer by setting it to ``None``.
  
  graph_models: Sequence of models
      Models can be ``str``, ``autogl.module.model.BaseAutoModel``, 
      ``autogl.module.model.encoders.BaseEncoderMaintainer`` or a tuple of (encoder, decoder) 
      if need to specify both encoder and decoder. Encoder can be ``str`` or
      ``autogl.module.model.encoders.BaseEncoderMaintainer``, and decoder can be ``str``
      or ``autogl.module.model.decoders.BaseDecoderMaintainer``.
  
  nas_algorithms: (list of) autogl.module.nas.algorithm.BaseNAS or str (Optional)
      The (name of) nas algorithms used. Default ``None``.
  
  nas_spaces: (list of) autogl.module.nas.space.BaseSpace or str (Optional)
      The (name of) nas spaces used. Default ``None``.
  
  nas_estimators: (list of) autogl.module.nas.estimator.BaseEstimator or str (Optional)
      The (name of) nas estimators used. Default ``None``.
  
  hpo_module: autogl.module.hpo.BaseHPOptimizer or str or None
      The (name of) hpo module used to search for best hyper parameters. Default ``anneal``.
      Disable hpo by setting it to ``None``.
  
  ensemble_module: autogl.module.ensemble.BaseEnsembler or str or None
      The (name of) ensemble module used to ensemble the multi-models found. Default ``voting``.
      Disable ensemble by setting it to ``None``.
  
  max_evals: int (Optional)
      If given, will set the number eval times the hpo module will use.
      Only be effective when hpo_module is ``str``. Default ``None``.
  
  default_trainer: str (Optional)
      The (name of) the trainer used in this solver. Default to ``NodeClassificationFull``.
  
  trainer_hp_space: list of dict (Optional)
      trainer hp space or list of trainer hp spaces configuration.
      If a single trainer hp is given, will specify the hp space of trainer for every model.
      If a list of trainer hp is given, will specify every model with corrsponding
      trainer hp space.
      Default ``None``.
  
  model_hp_spaces: list of list of dict (Optional)
      model hp space configuration.
      If given, will specify every hp space of every passed model. Default ``None``.
      If the encoder(-decoder) is passed, the space should be a dict containing keys "encoder"
      and "decoder", specifying the detailed encoder decoder hp spaces.
  
  size: int (Optional)
      The max models ensemble module will use. Default ``None``.
  
  device: torch.device or str
      The device where model will be running on. If set to ``auto``, will use gpu when available.
      You can also specify the device by directly giving ``gpu`` or ``cuda:0``, etc.
      Default ``auto``.
class_docstr_tok: ["Auto","Multi-class","Graph","Node","Classifier",".","Used","to","automatically","solve","the","node","classification","problems",".","Parameters","--","--","--","--","--","feature_module",":","autogl.module.feature.BaseFeatureEngineer","or","str","or","None","The","(","name","of",")","auto","feature","engineer","used","to","process","the","given","dataset",".","Default","``","deepgl","``",".","Disable","feature","engineer","by","setting","it","to","``","None","``",".","graph_models",":","Sequence","of","models","Models","can","be","``","str","``",",","``","autogl.module.model.BaseAutoModel","``",",","``","autogl.module.model.encoders.BaseEncoderMaintainer","``","or","a","tuple","of","(","encoder",",","decoder",")","if","need","to","specify","both","encoder","and","decoder",".","Encoder","can","be","``","str","``","or","``","autogl.module.model.encoders.BaseEncoderMaintainer","``",",","and","decoder","can","be","``","str","``","or","``","autogl.module.model.decoders.BaseDecoderMaintainer","``",".","nas_algorithms",":","(","list","of",")","autogl.module.nas.algorithm.BaseNAS","or","str","(","Optional",")","The","(","name","of",")","nas","algorithms","used",".","Default","``","None","``",".","nas_spaces",":","(","list","of",")","autogl.module.nas.space.BaseSpace","or","str","(","Optional",")","The","(","name","of",")","nas","spaces","used",".","Default","``","None","``",".","nas_estimators",":","(","list","of",")","autogl.module.nas.estimator.BaseEstimator","or","str","(","Optional",")","The","(","name","of",")","nas","estimators","used",".","Default","``","None","``",".","hpo_module",":","autogl.module.hpo.BaseHPOptimizer","or","str","or","None","The","(","name","of",")","hpo","module","used","to","search","for","best","hyper","parameters",".","Default","``","anneal","``",".","Disable","hpo","by","setting","it","to","``","None","``",".","ensemble_module",":","autogl.module.ensemble.BaseEnsembler","or","str","or","None","The","(","name","of",")","ensemble","module","used","to","ensemble","the","multi-models","found",".","Default","``","voting","``",".","Disable","ensemble","by","setting","it","to","``","None","``",".","max_evals",":","int","(","Optional",")","If","given",",","will","set","the","number","eval","times","the","hpo","module","will","use",".","Only","be","effective","when","hpo_module","is","``","str","``",".","Default","``","None","``",".","default_trainer",":","str","(","Optional",")","The","(","name","of",")","the","trainer","used","in","this","solver",".","Default","to","``","NodeClassificationFull","``",".","trainer_hp_space",":","list","of","dict","(","Optional",")","trainer","hp","space","or","list","of","trainer","hp","spaces","configuration",".","If","a","single","trainer","hp","is","given",",","will","specify","the","hp","space","of","trainer","for","every","model",".","If","a","list","of","trainer","hp","is","given",",","will","specify","every","model","with","corrsponding","trainer","hp","space",".","Default","``","None","``",".","model_hp_spaces",":","list","of","list","of","dict","(","Optional",")","model","hp","space","configuration",".","If","given",",","will","specify","every","hp","space","of","every","passed","model",".","Default","``","None","``",".","If","the","encoder","(","-decoder",")","is","passed",",","the","space","should","be","a","dict","containing","keys","``","encoder","''","and","``","decoder","''",",","specifying","the","detailed","encoder","decoder","hp","spaces",".","size",":","int","(","Optional",")","The","max","models","ensemble","module","will","use",".","Default","``","None","``",".","device",":","torch.device","or","str","The","device","where","model","will","be","running","on",".","If","set","to","``","auto","``",",","will","use","gpu","when","available",".","You","can","also","specify","the","device","by","directly","giving","``","gpu","``","or","``","cuda:0","``",",","etc",".","Default","``","auto","``","."]
docstr: Fit current solver on given dataset.
  
  Parameters
  ----------
  dataset: autogl.data.Dataset
      The dataset needed to fit on. This dataset must have only one graph.
  
  time_limit: int
      The time limit of the whole fit process (in seconds). If set below 0,
      will ignore time limit. Default ``-1``.
  
  inplace: bool
      Whether we process the given dataset in inplace manner. Default ``False``.
      Set it to True if you want to save memory by modifying the given dataset directly.
  
  train_split: float or int (Optional)
      The train ratio (in ``float``) or number (in ``int``) of dataset. If you want to
      use default train/val/test split in dataset, please set this to ``None``.
      Default ``None``.
  
  val_split: float or int (Optional)
      The validation ratio (in ``float``) or number (in ``int``) of dataset. If you want
      to use default train/val/test split in dataset, please set this to ``None``.
      Default ``None``.
  
  balanced: bool
      Wether to create the train/valid/test split in a balanced way.
      If set to ``True``, the train/valid will have the same number of different classes.
      Default ``True``.
  
  evaluation_method: (list of) str or autogl.module.train.evaluation
      A (list of) evaluation method for current solver. If ``infer``, will automatically
      determine. Default ``infer``.
  
  seed: int (Optional)
      The random seed. If set to ``None``, will run everything at random.
      Default ``None``.
  
  Returns
  -------
  self: autogl.solver.AutoNodeClassifier
      A reference of current solver.
docstr_tok: ["Fit","current","solver","on","given","dataset",".","Parameters","--","--","--","--","--","dataset",":","autogl.data.Dataset","The","dataset","needed","to","fit","on",".","This","dataset","must","have","only","one","graph",".","time_limit",":","int","The","time","limit","of","the","whole","fit","process","(","in","seconds",")",".","If","set","below","0",",","will","ignore","time","limit",".","Default","``","-1","``",".","inplace",":","bool","Whether","we","process","the","given","dataset","in","inplace","manner",".","Default","``","False","``",".","Set","it","to","True","if","you","want","to","save","memory","by","modifying","the","given","dataset","directly",".","train_split",":","float","or","int","(","Optional",")","The","train","ratio","(","in","``","float","``",")","or","number","(","in","``","int","``",")","of","dataset",".","If","you","want","to","use","default","train\/val\/test","split","in","dataset",",","please","set","this","to","``","None","``",".","Default","``","None","``",".","val_split",":","float","or","int","(","Optional",")","The","validation","ratio","(","in","``","float","``",")","or","number","(","in","``","int","``",")","of","dataset",".","If","you","want","to","use","default","train\/val\/test","split","in","dataset",",","please","set","this","to","``","None","``",".","Default","``","None","``",".","balanced",":","bool","Wether","to","create","the","train\/valid\/test","split","in","a","balanced","way",".","If","set","to","``","True","``",",","the","train\/valid","will","have","the","same","number","of","different","classes",".","Default","``","True","``",".","evaluation_method",":","(","list","of",")","str","or","autogl.module.train.evaluation","A","(","list","of",")","evaluation","method","for","current","solver",".","If","``","infer","``",",","will","automatically","determine",".","Default","``","infer","``",".","seed",":","int","(","Optional",")","The","random","seed",".","If","set","to","``","None","``",",","will","run","everything","at","random",".","Default","``","None","``",".","Returns","--","--","--","-","self",":","autogl.solver.AutoNodeClassifier","A","reference","of","current","solver","."]
code: def fit(
      self,
      dataset,
      time_limit=-1,
      inplace=False,
      train_split=None,
      val_split=None,
      balanced=True,
      evaluation_method="infer",
      seed=None,
  ) -> "AutoNodeClassifier":
      """
      Fit current solver on given dataset.
  
      Parameters
      ----------
      dataset: autogl.data.Dataset
          The dataset needed to fit on. This dataset must have only one graph.
  
      time_limit: int
          The time limit of the whole fit process (in seconds). If set below 0,
          will ignore time limit. Default ``-1``.
  
      inplace: bool
          Whether we process the given dataset in inplace manner. Default ``False``.
          Set it to True if you want to save memory by modifying the given dataset directly.
  
      train_split: float or int (Optional)
          The train ratio (in ``float``) or number (in ``int``) of dataset. If you want to
          use default train/val/test split in dataset, please set this to ``None``.
          Default ``None``.
  
      val_split: float or int (Optional)
          The validation ratio (in ``float``) or number (in ``int``) of dataset. If you want
          to use default train/val/test split in dataset, please set this to ``None``.
          Default ``None``.
  
      balanced: bool
          Wether to create the train/valid/test split in a balanced way.
          If set to ``True``, the train/valid will have the same number of different classes.
          Default ``True``.
  
      evaluation_method: (list of) str or autogl.module.train.evaluation
          A (list of) evaluation method for current solver. If ``infer``, will automatically
          determine. Default ``infer``.
  
      seed: int (Optional)
          The random seed. If set to ``None``, will run everything at random.
          Default ``None``.
  
      Returns
      -------
      self: autogl.solver.AutoNodeClassifier
          A reference of current solver.
      """
      set_seed(seed)
  
      if time_limit < 0:
          time_limit = 3600 * 24
      time_begin = time.time()
  
      graph_data = get_graph_from_dataset(dataset, 0)
      all_labels = get_graph_labels(graph_data)
      num_classes = all_labels.max().item() + 1
  
      # initialize leaderboard
      if evaluation_method == "infer":
          if hasattr(dataset, "metric"):
              evaluation_method = [dataset.metric]
          else:
              num_of_label = num_classes
              if num_of_label == 2:
                  evaluation_method = ["auc"]
              else:
                  evaluation_method = ["acc"]
      assert isinstance(evaluation_method, list)
      evaluator_list = get_feval(evaluation_method)
  
      self.leaderboard = LeaderBoard(
          [e.get_eval_name() for e in evaluator_list],
          {
              e.get_eval_name(): e.is_higher_better()
              for e in evaluator_list
          },
      )
      # set up the dataset
      if train_split is not None and val_split is not None:
          size = get_graph_node_number(graph_data)
          if balanced:
              train_split = (
                  train_split
                  if train_split > 1
                  else int(train_split * size)
              )
              val_split = (
                  val_split if val_split > 1 else int(val_split * size)
              )
              dataset = utils.random_splits_mask_class(
                  dataset,
                  num_train_per_class=train_split // num_classes,
                  num_val_per_class=val_split // num_classes,
                  seed=seed,
              )
          else:
              train_split = (
                  train_split if train_split < 1 else train_split / size
              )
              val_split = (
                  val_split if val_split < 1 else val_split / size
              )
              dataset = utils.random_splits_mask(
                  dataset, train_ratio=train_split, val_ratio=val_split
              )
      else:
          assert (
              get_graph_masks(graph_data, "train") is not None
              and get_graph_masks(graph_data, "val") is not None
          ), (
              "The dataset has no default train/val split! Please manually pass "
              "train and val ratio."
          )
          LOGGER.info(
              "Use the default train/val/test ratio in given dataset"
          )
  
      # feature engineering
      # if self.feature_module is not None:
      #     dataset = self.feature_module.fit_transform(dataset, inplace=inplace)
  
      self.dataset = dataset
  
      # check whether the dataset has features.
      # currently we only support graph classification with features.
  
      graph_data = get_graph_from_dataset(dataset, 0)
      feat = get_graph_node_features(graph_data)
      assert feat is not None, (
          "Does not support fit on non node-feature dataset!"
          " Please add node features to dataset or specify feature engineers that generate"
          " node features."
      )
  
      num_features = feat.size(-1)
  
      # initialize graph networks
      self._init_graph_module(
          self.gml,
          num_features=num_features,
          num_classes=num_classes,
          feval=evaluator_list,
          device=self.runtime_device,
          loss="nll_loss"
          if not hasattr(dataset, "loss")
          else self.dataset.loss,
      )
  
      if self.nas_algorithms is not None:
          # perform neural architecture search
          self._init_nas_module(
              num_features=num_features,
              num_classes=num_classes,
              feval=evaluator_list,
              device=self.runtime_device,
              loss="nll_loss"
              if not hasattr(dataset, "loss")
              else dataset.loss,
          )
  
          assert not isinstance(self._default_trainer, list) or len(
              self.nas_algorithms
          ) == len(self._default_trainer) - len(
              self.graph_model_list
          ), "length of default trainer should match total graph models and nas models passed"
  
          # perform nas and add them to model list
          idx_trainer = len(self.graph_model_list)
          for algo, space, estimator in zip(
              self.nas_algorithms, self.nas_spaces, self.nas_estimators
          ):
              model = algo.search(space, self.dataset, estimator)
              # insert model into default trainer
              if isinstance(self._default_trainer, list):
                  train_name = self._default_trainer[idx_trainer]
                  idx_trainer += 1
              else:
                  train_name = self._default_trainer
              if isinstance(train_name, str):
                  trainer = TRAINER_DICT[train_name](
                      model=model,
                      num_features=num_features,
                      num_classes=num_classes,
                      loss="nll_loss"
                      if not hasattr(dataset, "loss")
                      else dataset.loss,
                      feval=evaluator_list,
                      device=self.runtime_device,
                      init=False,
                  )
              elif isinstance(
                  train_name, BaseNodeClassificationTrainer
              ):
                  trainer = train_name
                  trainer.encoder = model
                  trainer.num_features = num_features
                  trainer.num_classes = num_classes
                  trainer.loss = (
                      "nll_loss"
                      if not hasattr(dataset, "loss")
                      else dataset.loss
                  )
                  trainer.feval = evaluator_list
                  trainer.to(self.runtime_device)
              else:
                  raise ValueError()
              self.graph_model_list.append(trainer)
  
      # train the models and tune hpo
      result_valid = []
      names = []
      for idx, model in enumerate(self.graph_model_list):
          model: BaseNodeClassificationTrainer
          time_for_each_model = (
              time_limit - time.time() + time_begin
          ) / (len(self.graph_model_list) - idx)
          if self.hpo_module is None:
              model.initialize()
              model.train(self.dataset, True)
              optimized = model
          else:
              optimized, _ = self.hpo_module.optimize(
                  trainer=model,
                  dataset=self.dataset,
                  time_limit=time_for_each_model,
              )
          # to save memory, all the trainer derived will be mapped to cpu
          optimized.to(torch.device("cpu"))
          name = str(optimized) + "_idx%d" % (idx)
          names.append(name)
          performance_on_valid, _ = optimized.get_valid_score(
              return_major=False
          )
          result_valid.append(
              optimized.get_valid_predict_proba().cpu().numpy()
          )
          self.leaderboard.insert_model_performance(
              name,
              dict(
                  zip(
                      [e.get_eval_name() for e in evaluator_list],
                      performance_on_valid,
                  )
              ),
          )
          self.trained_models[name] = optimized
  
      # fit the ensemble model
      if self.ensemble_module is not None:
          performance = self.ensemble_module.fit(
              result_valid,
              all_labels[get_graph_masks(graph_data, "val")]
              .cpu()
              .numpy(),
              names,
              evaluator_list,
              n_classes=num_classes,
          )
          self.leaderboard.insert_model_performance(
              "ensemble",
              dict(
                  zip(
                      [e.get_eval_name() for e in evaluator_list],
                      performance,
                  )
              ),
          )
  
      return self
  
imports: import time
  import json
  from copy import deepcopy
  from typing import Sequence
  import torch
  import numpy
  import yaml
  from .base import BaseClassifier
  from ..base import _parse_hp_space, _initialize_single_model, _parse_model_hp
  from ...module.feature import FEATURE_DICT
  from ...module.train import TRAINER_DICT, BaseNodeClassificationTrainer
  from ...module.train import get_feval
  from ...module.nas.space import NAS_SPACE_DICT
  from ...module.nas.algorithm import NAS_ALGO_DICT
  from ...module.nas.estimator import NAS_ESTIMATOR_DICT, BaseEstimator
  from ..utils import LeaderBoard, get_graph_from_dataset, get_graph_labels, get_graph_masks, get_graph_node_features, get_graph_node_number, set_seed
  from ...datasets import utils
  from ...utils import get_logger
label_desc: Use image node_id 4 for calling the AutoNodeClassifier obj's underlying member method code with example usage: obj.fit(dataset, time_limit, inplace, train_split, val_split, balanced, evaluation_method, seed) and returns: self