class_docstr: TFX Tuner executor impl as a worker in a Google Cloud AI Platform job.
class_docstr_tok: ["TFX","Tuner","executor","impl","as","a","worker","in","a","Google","Cloud","AI","Platform","job","."]
docstr: Conducts a single search loop, setting up chief oracle if necessary.
docstr_tok: ["Conducts","a","single","search","loop",",","setting","up","chief","oracle","if","necessary","."]
code: def _search(
      self,
      input_dict: Dict[str, List[types.Artifact]],
      output_dict: Dict[str, List[types.Artifact]],
      exec_properties: Dict[str, List[types.Artifact]],
  ):
      """Conducts a single search loop, setting up chief oracle if necessary."""
  
      # If not distributed, simply conduct search and return.
      if self._tuner_id is None:
          return tuner_executor.search(
              input_dict, exec_properties, _WORKING_DIRECTORY
          )
  
      if _need_chief_oracle(exec_properties):
          # If distributed search, and this node is chief, start a chief oracle
          # process before conducting search by itself.
          if self._is_chief:
              # Tuner with chief oracle will block forever. As such, start it in
              # a subprocess and manage its lifecycle by the main process.
              # Note that the Tuner with chief oracle does not run search loop,
              # hence does not run TensorFlow code in the subprocess.
              self._start_chief_oracle_in_subprocess(
                  input_dict, output_dict, exec_properties
              )
  
              # We started the chief in a subprocess. Now we're reusing the original
              # process as a tuner worker to run trials.
              self._is_chief = False
  
          # If distributed, both master and worker need to know where the oracle is.
          # Per KerasTuner's interface, it is configured through env variables.
          # This only affects the current main process, which is designed to be
          # single-threaded. As such, mutation of this otherwise global state is
          # safe.
          os.environ["KERASTUNER_ORACLE_IP"] = self._master_addr
          os.environ["KERASTUNER_ORACLE_PORT"] = self._master_port
  
          logging.info(
              "Oracle chief is known to be at: %s:%s",
              os.environ["KERASTUNER_ORACLE_IP"],
              os.environ["KERASTUNER_ORACLE_PORT"],
          )
  
      # Conduct tuner search loop, regardless of master or worker.
      # There is only one Tuner instance in the current process, as such,
      # controllling the id of the Tuner instance via environment variable
      # is safe.
      os.environ["KERASTUNER_TUNER_ID"] = self._tuner_id
      logging.info(
          "Setting KERASTUNER_TUNER_ID with %s",
          os.environ["KERASTUNER_TUNER_ID"],
      )
  
      # Printing tuning summary in distributed setting involves RPC calls to Chief
      # worker. Chief worker stops after all tuning trials are finished and might
      # be unavailable for such RPC calls.
      return tuner_executor.search(
          input_dict=input_dict,
          exec_properties=exec_properties,
          working_dir=_WORKING_DIRECTORY,
          print_tuning_summary=False,
      )
  
imports: import datetime
  import json
  import os
  from typing import Any, Dict, List
  from absl import logging
  from tfx import types
  from tfx.components.tuner import executor
  from tfx.dsl.components.base import base_executor
  from tfx.extensions.google_cloud_ai_platform import constants
  from tfx.extensions.google_cloud_ai_platform import runner
  from tfx.extensions.google_cloud_ai_platform.trainer import executor
  from tfx.types import standard_component_specs
  from tfx.utils import doc_controls
  from tfx.utils import json_utils
  from tfx.utils import name_utils
  import multiprocessing
label_desc: Use image node_id 3 for calling the _WorkerExecutor obj's underlying member method code with example usage: obj._search(input_dict, output_dict, exec_properties) and returns: tuner_executor, tuner_executor