class_docstr: A bracket in BOHB, all the information of a bracket is managed by
  an instance of this class.
  
  Parameters
  ----------
  s: int
      The current Successive Halving iteration index.
  s_max: int
      total number of Successive Halving iterations
  eta: float
      In each iteration, a complete run of sequential halving is executed. In it,
              after evaluating each configuration on the same subset size, only a fraction of
              1/eta of them 'advances' to the next round.
      max_budget : float
              The largest budget to consider. Needs to be larger than min_budget!
              The budgets will be geometrically distributed
      :math:`a^2 + b^2 = c^2 \sim \eta^k` for :math:`k\in [0, 1, ... , num\_subsets - 1]`.
  optimize_mode: str
      optimize mode, 'maximize' or 'minimize'
class_docstr_tok: ["A","bracket","in","BOHB",",","all","the","information","of","a","bracket","is","managed","by","an","instance","of","this","class",".","Parameters","--","--","--","--","--","s",":","int","The","current","Successive","Halving","iteration","index",".","s_max",":","int","total","number","of","Successive","Halving","iterations","eta",":","float","In","each","iteration",",","a","complete","run","of","sequential","halving","is","executed",".","In","it",",","after","evaluating","each","configuration","on","the","same","subset","size",",","only","a","fraction","of","1\/eta","of","them","'advances","'","to","the","next","round",".","max_budget",":","float","The","largest","budget","to","consider",".","Needs","to","be","larger","than","min_budget","!","The","budgets","will","be","geometrically","distributed",":","math",":","`","a^2","+","b^2","=","c^2","\\sim","\\eta^k","`","for",":","math",":","`","k\\in","[","0",",","1",",","...",",","num\\_subsets","-","1","]","`",".","optimize_mode",":","str","optimize","mode",",","'maximize","'","or","'minimize","'"]
docstr: If the trial is finished and the corresponding round (i.e., i) has all its trials finished,
  it will choose the top k trials for the next round (i.e., i+1)
  
  Parameters
  ----------
  i: int
      the ith round
  
  Returns
  -------
  new trial or None:
      If we have generated new trials after this trial end, we will return a new trial parameters.
      Otherwise, we will return None.
code: def inform_trial_end(self, i):
      """If the trial is finished and the corresponding round (i.e., i) has all its trials finished,
      it will choose the top k trials for the next round (i.e., i+1)
  
      Parameters
      ----------
      i: int
          the ith round
  
      Returns
      -------
      new trial or None:
          If we have generated new trials after this trial end, we will return a new trial parameters.
          Otherwise, we will return None.
      """
      global _KEY
      self.num_finished_configs[i] += 1
      logger.debug(
          "bracket id: %d, round: %d %d, finished: %d, all: %d",
          self.s,
          self.i,
          i,
          self.num_finished_configs[i],
          self.num_configs_to_run[i],
      )
      if (
          self.num_finished_configs[i] >= self.num_configs_to_run[i]
          and self.no_more_trial is False
      ):
          # choose candidate configs from finished configs to run in the next round
          assert self.i == i + 1
          # finish this bracket
          if self.i > self.s:
              self.no_more_trial = True
              return None
          this_round_perf = self.configs_perf[i]
          if self.optimize_mode is OptimizeMode.Maximize:
              sorted_perf = sorted(
                  this_round_perf.items(),
                  key=lambda kv: kv[1][1],
                  reverse=True,
              )  # reverse
          else:
              sorted_perf = sorted(
                  this_round_perf.items(), key=lambda kv: kv[1][1]
              )
          logger.debug(
              "bracket %s next round %s, sorted hyper configs: %s",
              self.s,
              self.i,
              sorted_perf,
          )
          next_n, next_r = self.get_n_r()
          logger.debug(
              "bracket %s next round %s, next_n=%d, next_r=%d",
              self.s,
              self.i,
              next_n,
              next_r,
          )
          hyper_configs = dict()
          for k in range(next_n):
              params_id = sorted_perf[k][0]
              params = self.hyper_configs[i][params_id]
              params[_KEY] = next_r  # modify r
              # generate new id
              increased_id = params_id.split("_")[-1]
              new_id = create_bracket_parameter_id(
                  self.s, self.i, increased_id
              )
              hyper_configs[new_id] = params
          self._record_hyper_configs(hyper_configs)
          return [[key, value] for key, value in hyper_configs.items()]
      return None
  
imports: import sys
  import math
  import logging
  from schema import Schema, Optional
  import ConfigSpace
  import ConfigSpace.hyperparameters
  from ConfigSpace.read_and_write import pcs_new
  import nni
  from nni import ClassArgsValidator
  from nni.runtime.tuner_command_channel import CommandType
  from nni.runtime.msg_dispatcher_base import MsgDispatcherBase
  from nni.utils import OptimizeMode, MetricType, extract_scalar_reward
  from nni.runtime.common import multi_phase_enabled
  from .config_generator import CG_BOHB
label_desc: Use image node_id 6 for calling the Bracket obj's underlying member method code with example usage: obj.inform_trial_end(i) and returns: None, unknown, None