code: def on_run_end(self):
      self.trainer._logger_connector.epoch_end_reached()
  
      # hook
      self._evaluation_epoch_end(self._outputs)
      self._outputs = []  # free memory
  
      # hook
      self._on_evaluation_epoch_end()
  
      logged_outputs, self._logged_outputs = (
          self._logged_outputs,
          [],
      )  # free memory
      # include any logged outputs on epoch_end
      epoch_end_logged_outputs = (
          self.trainer._logger_connector.update_eval_epoch_metrics()
      )
      all_logged_outputs = dict(
          ChainMap(*logged_outputs)
      )  # list[dict] -> dict
      all_logged_outputs.update(epoch_end_logged_outputs)
      for dl_outputs in logged_outputs:
          dl_outputs.update(epoch_end_logged_outputs)
  
      # log metrics
      self.trainer._logger_connector.log_eval_end_metrics(
          all_logged_outputs
      )
  
      # hook
      self._on_evaluation_end()
  
      if self.verbose and self.trainer.is_global_zero:
          invalidInputError(
              self.trainer.state.stage is not None, "stage is wrong"
          )
          self._print_results(logged_outputs, self.trainer.state.stage)
  
      return logged_outputs
  
imports: from typing import Any
  import torch
  import time
  from pytorch_lightning.callbacks import Callback
  from pytorch_lightning.loops.dataloader.evaluation_loop import EvaluationLoop
  from bigdl.nano.utils.common import invalidInputError
  from collections import ChainMap
  from torchmetrics import Metric
label_desc: Use image node_id 2 for calling the CustomEvaluationLoop obj's underlying member method code with example usage: obj.on_run_end() and returns: logged_outputs