docstr: Write log files(event files)
  
  The log files is arranged as following:
  self.logs_dir
  |--eventfile_all
  |--Trail_1
  |  |--eventfile_1
  |--Trail_2
  |  |--eventfile_2
  ...
  :param config: A dictionary. Keys are trail name,
      value is a dictionary indicates the trail config
  :param metric: A dictionary. Keys are trail name,
      value is a dictionary indicates the trail metric results for each iteration
  
  Example:
  Config = {"run1":{"lr":0.001, "hidden_units": 32},
            "run2":{"lr":0.01, "hidden_units": 64}}
  Metric = {"run1":{"acc":0.91, "time": 32.13},
            "run2":{"acc":[0.93, 0.95], "time": [61.33, 62.44]}}
  
  Note that the keys of config and metric should be exactly the same
docstr_tok: ["Write","log","files","(","event","files",")","The","log","files","is","arranged","as","following",":","self.logs_dir","|","--","eventfile_all","|","--","Trail_1","|","|","--","eventfile_1","|","--","Trail_2","|","|","--","eventfile_2","...",":","param","config",":","A","dictionary",".","Keys","are","trail","name",",","value","is","a","dictionary","indicates","the","trail","config",":","param","metric",":","A","dictionary",".","Keys","are","trail","name",",","value","is","a","dictionary","indicates","the","trail","metric","results","for","each","iteration","Example",":","Config","=","{","``","run1","''",":","{","``","lr","''",":0.001",",","``","hidden_units","''",":","32","}",",","``","run2","''",":","{","``","lr","''",":0.01",",","``","hidden_units","''",":","64","}","}","Metric","=","{","``","run1","''",":","{","``","acc","''",":0.91",",","``","time","''",":","32.13","}",",","``","run2","''",":","{","``","acc","''",":","[","0.93",",","0.95","]",",","``","time","''",":","[","61.33",",","62.44","]","}","}","Note","that","the","keys","of","config","and","metric","should","be","exactly","the","same"]
code: def run(self, config, metric):
      """
      Write log files(event files)
  
      The log files is arranged as following:
      self.logs_dir
      |--eventfile_all
      |--Trail_1
      |  |--eventfile_1
      |--Trail_2
      |  |--eventfile_2
      ...
      :param config: A dictionary. Keys are trail name,
          value is a dictionary indicates the trail config
      :param metric: A dictionary. Keys are trail name,
          value is a dictionary indicates the trail metric results for each iteration
  
      Example:
      Config = {"run1":{"lr":0.001, "hidden_units": 32},
                "run2":{"lr":0.01, "hidden_units": 64}}
      Metric = {"run1":{"acc":0.91, "time": 32.13},
                "run2":{"acc":[0.93, 0.95], "time": [61.33, 62.44]}}
  
      Note that the keys of config and metric should be exactly the same
      """
      # keys check
      invalidInputError(
          config.keys() == metric.keys(),
          "The keys of config and metric should be exactly the same",
      )
  
      new_config = {}
      hparam_domain_discrete = {}
      for key in config.keys():
          new_config[key] = {}
          for k, value in config[key].items():
              if value is None:
                  pass
              if type(value) in VALID_SUMMARY_TYPES:
                  new_config[key][f"{self.name}/" + k] = value
              if type(
                  value
              ) in VALID_NUMPY_SUMMARY_TYPES and not np.isnan(value):
                  new_config[key][f"{self.name}/" + k] = float(value)
              if type(value) in VALID_SEQ_SUMMARY_TYPES:
                  new_config[key][f"{self.name}/" + k] = str(value)
                  if f"{self.name}/" + k in hparam_domain_discrete:
                      hparam_domain_discrete[f"{self.name}/" + k].add(
                          str(value)
                      )
                  else:
                      hparam_domain_discrete[f"{self.name}/" + k] = set(
                          [str(value)]
                      )
      for k, v in hparam_domain_discrete.items():
          hparam_domain_discrete[k] = list(v)
      for key in new_config.keys():
          if new_config[key] == {}:
              del new_config[key]
  
      new_metric = {}
      for key in metric.keys():
          new_metric[key] = {}
          for k, value in metric[key].items():
              if not isinstance(value, list):
                  value = [value]
              if value[-1] is None:
                  continue
              if type(
                  value[-1]
              ) in VALID_SUMMARY_TYPES and not math.isnan(value[-1]):
                  new_metric[key][f"{self.name}/" + k] = value
              if type(
                  value[-1]
              ) in VALID_NUMPY_SUMMARY_TYPES and not np.isnan(
                  value[-1]
              ):
                  new_metric[key][f"{self.name}/" + k] = list(
                      map(float, value)
                  )
      for key in new_metric.keys():
          if new_metric[key] == {}:
              del new_metric[key]
  
      # hparams log write
      for key in new_metric.keys():
          self._write_hparams(
              new_config[key],
              new_metric[key],
              name=key.replace("/", "_"),
              hparam_domain_discrete=hparam_domain_discrete,
          )
  
file_path: BigDL/python/orca/src/bigdl/orca/automl/search/tensorboardlogger.py
imports: from ray.tune.utils import flatten_dict
  import numpy
  import os
  import math
  from torch.utils.tensorboard import SummaryWriter
  from torch.utils.tensorboard.summary import hparams
  from bigdl.dllib.utils.log4Error import *
label_desc: Use image node_id 2 for calling the TensorboardLogger obj's underlying member method code with example usage: obj.run(config, metric) without return types