class_docstr:     Callback for valuate the performance of the model.
  Args:
      actor_num_params: The number of parameters of the actor model.
      critic_num_params: The number of parameters of the critic model.
      initial_model_num_params: The number of parameters of the initial model.
      reward_model_num_params: The number of parameters of the reward model.
      enable_grad_checkpoint: Whether to enable gradient checkpointing.
      ignore_episodes: The number of episodes to ignore when calculating the performance.
code: def on_fit_end(self) -> None:
      avg_make_experience_duration = all_reduce_mean(
          self.make_experience_timer.duration, self.world_size
      )
      avg_learn_duration = all_reduce_mean(
          self.learn_timer.duration, self.world_size
      )
      avg_overall_duration = all_reduce_mean(
          self.overall_timer.duration, self.world_size
      )
  
      avg_make_experience_throughput = (
          self.make_experience_num_samples
          * self.world_size
          / (avg_make_experience_duration + 1e-12)
      )
      avg_make_experience_tflops = (
          self.make_experience_flop
          / 1e12
          / (avg_make_experience_duration + 1e-12)
      )
  
      avg_learn_throughput = (
          self.learn_num_samples
          * self.world_size
          / (avg_learn_duration + 1e-12)
      )
      avg_learn_tflops = (
          self.learn_flop / 1e12 / (avg_learn_duration + 1e-12)
      )
  
      num_effective_samples = (
          min(self.learn_num_samples, self.make_experience_num_samples)
          * self.world_size
      )
  
      avg_overall_throughput = num_effective_samples / (
          avg_overall_duration + 1e-12
      )
  
      overall_time_per_sample = divide(1, avg_overall_throughput)
      make_experience_time_per_sample = divide(
          avg_make_experience_duration, num_effective_samples
      )
      learn_time_per_sample = divide(
          avg_learn_duration, num_effective_samples
      )
  
      print_rank_0(
          f"Performance summary:\n"
          + f"Generate {self.make_experience_num_samples * self.world_size} samples, throughput: {avg_make_experience_throughput:.2f} samples/s, TFLOPS per GPU: {avg_make_experience_tflops:.2f}\n"
          + f"Train {self.learn_num_samples * self.world_size} samples, throughput: {avg_learn_throughput:.2f} samples/s, TFLOPS per GPU: {avg_learn_tflops:.2f}\n"
          + f"Overall throughput: {avg_overall_throughput:.2f} samples/s\n"
          + f"Overall time per sample: {overall_time_per_sample:.2f} s\n"
          + f"Make experience time per sample: {make_experience_time_per_sample:.2f} s, {make_experience_time_per_sample/overall_time_per_sample*100:.2f}%\n"
          + f"Learn time per sample: {learn_time_per_sample:.2f} s, {learn_time_per_sample/overall_time_per_sample*100:.2f}%"
      )
  
imports: from time import time
  from typing import Optional
  import torch
  import torch.distributed
  from coati.experience_maker import Experience
  from .base import Callback
label_desc: Use image node_id 8 for calling the PerformanceEvaluator obj's underlying member method code with example usage: obj.on_fit_end() without return types