code: def daemon(self):
      if self._is_thread_mode_and_not_main_process():
          return
  
      seconds_since_started = 0
      reported = 0
      last_iteration = 0
      fallback_to_sec_as_iterations = None
  
      # get max GPU ID, and make sure our active list is within range
      if self._active_gpus:
          # noinspection PyBroadException
          try:
              gpu_stat = self._gpustat.new_query()
              if max(self._active_gpus) > len(gpu_stat.gpus) - 1:
                  self._active_gpus = None
          except Exception:
              pass
  
      # add Task runtime_properties with the machine spec
      if Session.check_min_api_version("2.13"):
          try:
              machine_spec = self._get_machine_specs()
              if machine_spec:
                  # noinspection PyProtectedMember
                  self._task._set_runtime_properties(
                      runtime_properties=machine_spec
                  )
          except Exception as ex:
              logging.getLogger("clearml.resource_monitor").debug(
                  "Failed logging machine specification: {}".format(ex)
              )
  
      # last_iteration_interval = None
      # last_iteration_ts = 0
      # repeated_iterations = 0
      while True:
          last_report = time()
          current_report_frequency = (
              self._report_frequency
              if reported != 0
              else self._first_report_sec
          )
          while (time() - last_report) < current_report_frequency:
              # wait for self._sample_frequency seconds, if event set quit
              if self._event.wait(1.0 / self._sample_frequency):
                  return
              # noinspection PyBroadException
              try:
                  self._update_readouts()
              except Exception:
                  pass
  
          seconds_since_started += int(round(time() - last_report))
          # check if we do not report any metric (so it means the last iteration will not be changed)
          if fallback_to_sec_as_iterations is None:
              if IsTensorboardInit.tensorboard_used():
                  fallback_to_sec_as_iterations = False
              elif (
                  seconds_since_started >= self.wait_for_first_iteration
              ):
                  self._task.get_logger().report_text(
                      "ClearML Monitor: Could not detect iteration reporting, "
                      "falling back to iterations as seconds-from-start"
                  )
                  fallback_to_sec_as_iterations = True
          elif (
              fallback_to_sec_as_iterations is True
              and seconds_since_started
              <= self.max_check_first_iteration
          ):
              if self._check_logger_reported():
                  fallback_to_sec_as_iterations = False
                  self._task.get_logger().report_text(
                      "ClearML Monitor: Reporting detected, "
                      "reverting back to iteration based reporting"
                  )
  
          clear_readouts = True
          # if we do not have last_iteration, we just use seconds as iteration
          if fallback_to_sec_as_iterations:
              iteration = seconds_since_started
          else:
              iteration = self._task.get_last_iteration()
              if iteration < last_iteration:
                  # we started a new session?!
                  # wait out
                  clear_readouts = False
                  iteration = last_iteration
              elif iteration == last_iteration:
                  # repeated_iterations += 1
                  # if last_iteration_interval:
                  #     # to be on the safe side, we don't want to pass the actual next iteration
                  #     iteration += int(0.95*last_iteration_interval[0] * (seconds_since_started - last_iteration_ts)
                  #                      / last_iteration_interval[1])
                  # else:
                  #     iteration += 1
                  clear_readouts = False
                  iteration = last_iteration
              else:
                  # last_iteration_interval = (iteration - last_iteration, seconds_since_started - last_iteration_ts)
                  # repeated_iterations = 0
                  # last_iteration_ts = seconds_since_started
                  last_iteration = iteration
                  fallback_to_sec_as_iterations = False
                  clear_readouts = True
  
          # start reporting only when we figured out, if this is seconds based, or iterations based
          average_readouts = self._get_average_readouts()
          if fallback_to_sec_as_iterations is not None:
              for k, v in average_readouts.items():
                  # noinspection PyBroadException
                  try:
                      title = (
                          self._title_gpu
                          if k.startswith("gpu_")
                          else self._title_machine
                      )
                      # 3 points after the dot
                      value = round(v * 1000) / 1000.0
                      self._task.get_logger().report_scalar(
                          title=title,
                          series=k,
                          iteration=iteration,
                          value=value,
                      )
                  except Exception:
                      pass
              # clear readouts if this is update is not averaged
              if clear_readouts:
                  self._clear_readouts()
  
          # count reported iterations
          reported += 1
  
imports: import logging
  import os
  import platform
  import sys
  import warnings
  from time import time
  import psutil
  from pathlib2 import Path
  from typing import Text
  from .process.mp import BackgroundMonitor
  from ..backend_api import Session
  from ..binding.frameworks.tensorflow_bind import IsTensorboardInit
label_desc: Use image node_id 2 for calling the ResourceMonitor obj's underlying member method code with example usage: obj.daemon() without return types