code: def stop(self, report_speed=True):
      if not self.started:
          return
      self.started = False
      self.total_step_count += 1
      self.local_step_count += 1
      if self.total_step_count > self.start_step:
          torch.cuda.synchronize()
          self.end_time = time.time()
          duration = self.end_time - self.start_time
          self.total_elapsed_time += duration
  
          curr_samples_sec = (
              self.batch_size * self.num_workers
          ) / duration
  
          if report_speed:
              self.logging(
                  "{}/{}, RunningAvgSamplesPerSec={}, CurrSamplesPerSec={}, MemAllocated={}GB, MaxMemAllocated={}GB".format(
                      self.epoch_count,
                      self.local_step_count,
                      self.avg_samples_per_sec(),
                      curr_samples_sec,
                      round(
                          torch.cuda.memory_allocated() / 1024**3, 2
                      ),
                      round(
                          torch.cuda.max_memory_allocated() / 1024**3,
                          2,
                      ),
                  )
              )
              if self.monitor_memory:
                  virt_mem = psutil.virtual_memory()
                  swap = psutil.swap_memory()
                  self.logging(
                      "{}/{}, vm percent: {}, swap percent: {}".format(
                          self.epoch_count,
                          self.local_step_count,
                          virt_mem.percent,
                          swap.percent,
                      )
                  )
  
imports: import time
  import torch
  from numpy import mean
  from deepspeed.utils.logging import log_dist
  from deepspeed import comm
label_desc: Use image node_id 5 for calling the ThroughputTimer obj's underlying member method code with example usage: obj.stop(report_speed) without return types