class_docstr: Very simple timing wrapper, with context manager wrapping.
  Typical usage:
  
    with PerfTimer('forward_pass', perf_stats):
        model.forward(data)
    # ...
    with PerfTimer('backward_pass', perf_stats):
        model.backward(loss)
    # ...
    print(perf_stats.report_str())
  
  Note that timer stats accumulate by name, so you can as if resume them
  by re-using the name.
  
  You can also use it without context manager, i.e. via start() / stop() directly.
  
  If supplied PerfStats is constructed with use_cuda_events=True (which is default),
  then Cuda events will be added to correctly track time of async execution
  of Cuda kernels:
  
    with PerfTimer('foobar', perf_stats):
        some_cpu_work()
        schedule_some_cuda_work()
  
  In example above, the "Host" column will capture elapsed time from the perspective
  of the Python process, and "CudaEvent" column will capture elapsed time between
  scheduling of Cuda work (within the PerfTimer scope) and completion of this work,
  some of which might happen outside the PerfTimer scope.
  
  If perf_stats is None, using PerfTimer does nothing.
class_docstr_tok: ["Very","simple","timing","wrapper",",","with","context","manager","wrapping",".","Typical","usage",":","with","PerfTimer","(","'forward_pass","'",",","perf_stats",")",":","model.forward","(","data",")","#","...","with","PerfTimer","(","'backward_pass","'",",","perf_stats",")",":","model.backward","(","loss",")","#","...","print","(","perf_stats.report_str","(",")",")","Note","that","timer","stats","accumulate","by","name",",","so","you","can","as","if","resume","them","by","re-using","the","name",".","You","can","also","use","it","without","context","manager",",","i.e",".","via","start","(",")","\/","stop","(",")","directly",".","If","supplied","PerfStats","is","constructed","with","use_cuda_events=True","(","which","is","default",")",",","then","Cuda","events","will","be","added","to","correctly","track","time","of","async","execution","of","Cuda","kernels",":","with","PerfTimer","(","'foobar","'",",","perf_stats",")",":","some_cpu_work","(",")","schedule_some_cuda_work","(",")","In","example","above",",","the","``","Host","''","column","will","capture","elapsed","time","from","the","perspective","of","the","Python","process",",","and","``","CudaEvent","''","column","will","capture","elapsed","time","between","scheduling","of","Cuda","work","(","within","the","PerfTimer","scope",")","and","completion","of","this","work",",","some","of","which","might","happen","outside","the","PerfTimer","scope",".","If","perf_stats","is","None",",","using","PerfTimer","does","nothing","."]
code: def record(self):
      if self.skip:
          return
      assert not self._is_running
      self._perf_stats.update_with_timer(self)
  
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 6 for calling the PerfTimer obj's underlying member method code with example usage: obj.record() without return types