code: def objective(config):
      hp = config["hp"]
  
      experiment_name = session.get_experiment_name()
      trial_name = session.get_trial_name()
      print(
          f"experiment name: {experiment_name} trial name: {trial_name}"
      )
  
      core_v2.init(
          defaults=core_v2.DefaultConfig(
              name=experiment_name,
              hparams={
                  "hp": config["hp"],
              },
              # We need to pass a non-single searcher config to have the WebUI display our experiment
              # as HP search.
              searcher={
                  "name": "custom",
                  "metric": "loss",
                  "smaller_is_better": True,
              },
          ),
          unmanaged=core_v2.UnmanagedConfig(
              external_experiment_id=experiment_name,
              external_trial_id=trial_name,
          ),
      )
  
      try:
          for i in range(100):
              if (i + 1) % 10 == 0:
                  loss = hp + random.random()
                  print("metrics:", {"loss": loss})
                  core_v2.train.report_validation_metrics(
                      steps_completed=i, metrics={"loss": loss}
                  )
                  session.report({"iterations": i, "loss": loss})
      finally:
          # Note: this is not called when ASHA terminates a "bad" trial, so these trials will
          # stay in the RUNNING state until they're marked as errored after a timeout.
          # `tune.Trainable` interface should be implemented to support a proper cleanup,
          # see `ray_hp_search_cleanup.py`.
          core_v2.close()
  
file_path: determined/examples/features/unmanaged/ray/ray_hp_search.py
imports: import random
  import uuid
  import ray
  from ray import air, tune
  from ray.air import session
  from ray.tune.schedulers import AsyncHyperBandScheduler
  from determined.experimental import core_v2
label_desc: Use image node_id 1 for calling a global function with example usage: objective(config) without return types