class_docstr: Base class for Contextual Bandit Offline Evaluation algorithms. All algorihtms support evaluation of non-stationary
      policies, as required for exploration-exploitation.
class_docstr_tok: ["Base","class","for","Contextual","Bandit","Offline","Evaluation","algorithms",".","All","algorihtms","support","evaluation","of","non-stationary","policies",",","as","required","for","exploration-exploitation","."]
code: def log_metrics(self, step: Optional[int] = None) -> None:
      if get_rank() == 0:
          # only log from the main process
          logger.info(self.get_formatted_result_string())
          logger_ = self.logger
          if logger_ is not None:
              metric_dict = {
                  ### cumulative sum and average metrics ###
                  f"{self.metric_prefix}avg_reward": self.get_avg_reward(),
                  f"{self.metric_prefix}sum_weight_accepted": self.sum_weight_accepted.item(),
                  f"{self.metric_prefix}sum_weight_all_data": self.sum_weight_all_data.item(),
                  f"{self.metric_prefix}num_eval_model_updates": self.num_eval_model_updates.item(),
                  ### average values since last logging ###
                  f"{self.metric_prefix}frac_accepted": self.frac_accepted.item(),
                  f"{self.metric_prefix}avg_reward_accepted": self.avg_reward_accepted.item(),
                  f"{self.metric_prefix}avg_reward_rejected": self.avg_reward_rejected.item(),
                  f"{self.metric_prefix}avg_size_accepted": self.avg_size_accepted.item(),
                  f"{self.metric_prefix}avg_size_rejected": self.avg_size_rejected.item(),
                  f"{self.metric_prefix}accepted_rejected_reward_ratio": self.accepted_rejected_reward_ratio.item(),
                  f"{self.metric_prefix}avg_reward_all_data": self.avg_reward_all_data.item(),
              }
              logger_.log_metrics(metric_dict, step=step)
  
imports: import copy
  import logging
  from abc import ABC, abstractmethod
  from typing import Optional
  import torch
  from pytorch_lightning.loggers import LightningLoggerBase
  from reagent.core.types import CBInput
  from reagent.core.utils import get_rank
  from reagent.evaluation.cb.utils import add_importance_weights
label_desc: Use image node_id 9 for calling the BaseOfflineEval obj's underlying member method code with example usage: obj.log_metrics(step) without return types