class_docstr: XGBoost model
  
  Parameters
  ----------
  extractor : FeatureExtractor
      The feature extractor for the model.
  config : XGBConfig
      The XGBoost model config.
  num_warmup_samples : int
      The number of samples that are used for warmup, i.e., the first few samples are predicted
      with random results.
  early_stopping_rounds : int
      The number of rounds for early stopping.
  verbose_eval : int
      The verbose level when doing evaluation.
  average_peak_n : int
      The number to calculate average peak score.
  adaptive_training : bool
      Whether use adaptive training to reduce tuning time.
class_docstr_tok: ["XGBoost","model","Parameters","--","--","--","--","--","extractor",":","FeatureExtractor","The","feature","extractor","for","the","model",".","config",":","XGBConfig","The","XGBoost","model","config",".","num_warmup_samples",":","int","The","number","of","samples","that","are","used","for","warmup",",","i.e.",",","the","first","few","samples","are","predicted","with","random","results",".","early_stopping_rounds",":","int","The","number","of","rounds","for","early","stopping",".","verbose_eval",":","int","The","verbose","level","when","doing","evaluation",".","average_peak_n",":","int","The","number","to","calculate","average","peak","score",".","adaptive_training",":","bool","Whether","use","adaptive","training","to","reduce","tuning","time","."]
docstr: Update the cost model given running results.
  
  Parameters
  ----------
  context : TuneContext
      The tuning context.
  candidates : List[MeasureCandidate]
      The measure candidates.
  results : List[RunnerResult]
      The running results of the measure candidates.
docstr_tok: ["Update","the","cost","model","given","running","results",".","Parameters","--","--","--","--","--","context",":","TuneContext","The","tuning","context",".","candidates",":","List","[","MeasureCandidate","]","The","measure","candidates",".","results",":","List","[","RunnerResult","]","The","running","results","of","the","measure","candidates","."]
code: def update(
      self,
      context: "TuneContext",
      candidates: List[MeasureCandidate],
      results: List[RunnerResult],
  ) -> None:
      """Update the cost model given running results.
  
      Parameters
      ----------
      context : TuneContext
          The tuning context.
      candidates : List[MeasureCandidate]
          The measure candidates.
      results : List[RunnerResult]
          The running results of the measure candidates.
      """
      assert len(candidates) == len(results)
      if len(candidates) == 0:
          return
  
      # Step 1. Get the feature group
      new_group_hash = shash2hex(context.mod)
      group = self.data.get(new_group_hash, None)
  
      # Step 2. Extract features
      def _feature(x: NDArray) -> np.ndarray:
          return x.numpy().astype("float32")
  
      def _mean_cost(x: RunnerResult) -> float:
          if not x.run_secs:
              return 1e10
          return float(np.median([float(s) for s in x.run_secs]))
  
      new_features = [
          _feature(x)
          for x in self.extractor.extract_from(context, candidates)
      ]
      new_mean_costs = [_mean_cost(x) for x in results]
  
      # Filter instances with no features
      new_mean_costs = [
          c
          for i, c in enumerate(new_mean_costs)
          if len(new_features[i]) != 0
      ]
      new_mean_costs_np = np.array(new_mean_costs).astype("float32")
      new_features = [f for f in new_features if len(f) != 0]
      if not new_features:
          return
  
      # Steps 3. Run validation
      if group is not None and self.booster is not None:
          logger.debug(
              "XGB validation: %s",
              "\t".join(
                  f"{key}: {score:.6f}"
                  for key, score in self._validate(
                      xs=new_features,
                      ys=group.min_cost / new_mean_costs_np,
                  )
              ),
          )
  
      # Step 4. Add the features into the data points
      if group is None:
          group = FeatureGroup(
              group_hash=new_group_hash,
              features=new_features,
              costs=new_mean_costs_np,
          )
      else:
          group.append(new_features, new_mean_costs_np)
      self.data[new_group_hash] = group
      self.data_size += len(new_features)
  
      if (
          self.adaptive_training
          and self.data_size - self.last_train_size
          < self.last_train_size / 5
      ):
          # Set a training threshold related to `last_train_size` to reduce the training
          # overhead when there're too many results
          return
      self.last_train_size = self.data_size
  
      # Step 5. Re-train the model
      self._train(
          xs=list(
              itertools_chain.from_iterable(
                  [g.features for g in self.data.values()]
              )
          ),
          ys=np.concatenate(
              [g.min_cost / g.costs for g in self.data.values()],
              axis=0,
          ),
      )
  
imports: import os
  import tempfile
  from collections import OrderedDict
  from itertools import chain
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, NamedTuple, Optional, Tuple
  from typing_extensions import Literal
  import numpy
  from ...contrib.tar import tar, untar
  from ...runtime import NDArray
  from ..cost_model import PyCostModel
  from ..feature_extractor import FeatureExtractor
  from ..logging import get_logger
  from ..runner import RunnerResult
  from ..search_strategy import MeasureCandidate
  from ..utils import cpu_count, derived_object, shash2hex
  from .metric import max_curve
label_desc: Use image node_id 4 for calling the XGBModel obj's underlying member method code with example usage: obj.update(context, candidates, results) and returns: x, float, int