class_docstr: Accumulate stats (from timers) over many iterations
class_docstr_tok: ["Accumulate","stats","(","from","timers",")","over","many","iterations"]
docstr: Fancy column-aligned human-readable report.
  If using Cuda events, calling this invokes cuda.synchronize(), which is needed
  to capture pending Cuda work in the report.
docstr_tok: ["Fancy","column-aligned","human-readable","report",".","If","using","Cuda","events",",","calling","this","invokes","cuda.synchronize","(",")",",","which","is","needed","to","capture","pending","Cuda","work","in","the","report","."]
code: def report_str(self):
      """
      Fancy column-aligned human-readable report.
      If using Cuda events, calling this invokes cuda.synchronize(), which is needed
      to capture pending Cuda work in the report.
      """
      if self.use_cuda_events():
          torch.cuda.synchronize()
          self._process_cuda_events()
  
      name_width = max(len(k) for k in self._host_stats.keys())
  
      header = (
          "{:>" + str(name_width + 4) + "s}  {:>7s}    {:>7s}"
      ).format("Timer", "Host", "CudaEvent")
      row_fmt = (
          "{:>" + str(name_width + 4) + "s}: {:>7.2f} ms {:>7.2f} ms"
      )
  
      rows = []
      rows.append(header)
      for name, metric in self._host_stats.items():
          rows.append(
              row_fmt.format(
                  name,
                  metric.get_avg() * 1000.0,
                  self._cuda_stats[name].get_avg() * 1000.0,
              )
          )
      return "\n".join(rows)
  
imports: import logging
  from collections import defaultdict, deque
  from time import perf_counter
  from typing import List, Mapping, Optional, Tuple
  import torch
  from torch.cuda import Event
label_desc: Use image node_id 4 for calling the PerfStats obj's underlying member method code with example usage: obj.report_str() and returns: str