code: def test_custom_callback(rosenbrock):
      N_TRIALS = 40
  
      scenario = Scenario(rosenbrock.configspace, n_trials=N_TRIALS)
      callback = CustomCallback()
  
      # The intensify percentage indirectly influences the number of calls of configuration
      # sampling.
      intensifier = Intensifier(scenario, max_config_calls=1)
      initial_design = DefaultInitialDesign(scenario)
  
      smac = HyperparameterOptimizationFacade(
          scenario,
          rosenbrock.train,
          intensifier=intensifier,
          initial_design=initial_design,
          callbacks=[callback],
          overwrite=True,
      )
      smac.optimize()
  
      # Those functions are called only once
      assert callback.start_counter == 1
      assert callback.end_counter == 1
  
      assert callback.ask_start_counter == 40
      assert callback.ask_end_counter == 40
  
      assert callback.ask_start_counter == callback.tell_start_counter
      assert callback.ask_end_counter == callback.tell_end_counter
  
      assert callback.iteration_start_counter == 40
      assert callback.iteration_end_counter == 40
      assert (
          callback.iteration_start_counter
          == callback.iteration_end_counter
      )
  
      assert callback.next_configurations_start_counter == 40
      assert callback.next_configurations_end_counter == 40
  
imports: from __future__ import annotations
  from ConfigSpace import Configuration
  import smac
  from smac import HyperparameterOptimizationFacade, Scenario
  from smac.callback.callback import Callback
  from smac.initial_design import DefaultInitialDesign
  from smac.intensifier.intensifier import Intensifier
  from smac.runhistory import TrialInfo, TrialValue
label_desc: Use image node_id 2 for calling a global function with example usage: test_custom_callback(rosenbrock) without return types