class_docstr: Class used to track pytorch memory usage
  Arguments:
      detail(bool, default True): whether the function shows the detail gpu memory usage
      path(str): where to save log file
      verbose(bool, default False): whether show the trivial exception
      device(int): GPU number, default is 0
class_docstr_tok: ["Class","used","to","track","pytorch","memory","usage","Arguments",":","detail","(","bool",",","default","True",")",":","whether","the","function","shows","the","detail","gpu","memory","usage","path","(","str",")",":","where","to","save","log","file","verbose","(","bool",",","default","False",")",":","whether","show","the","trivial","exception","device","(","int",")",":","GPU","number",",","default","is","0"]
docstr: Track the GPU memory usage
docstr_tok: ["Track","the","GPU","memory","usage"]
code: def track(self):
      """
      Track the GPU memory usage
      """
      frameinfo = inspect.stack()[1]
      where_str = (
          frameinfo.filename
          + " line "
          + str(frameinfo.lineno)
          + ": "
          + frameinfo.function
      )
  
      if self.log_to_disk:
          file_name = self.gpu_profile_fn
      else:
          file_name = None
  
      with file_writer(file_name) as f:
          if self.begin:
              f.write(
                  f"GPU Memory Track | {datetime.datetime.now():%d-%b-%y-%H:%M:%S} |"
                  f" Total Tensor Used Memory:{self.get_tensor_usage():<7.1f}Mb"
                  f" Total Allocated Memory:{self.get_allocate_usage():<7.1f}Mb\n\n"
              )
              self.begin = False
  
          if self.print_detail is True:
              ts_list = [
                  (tensor.size(), tensor.dtype)
                  for tensor in self.get_tensors()
              ]
              new_tensor_sizes = {
                  (
                      type(x),
                      tuple(x.size()),
                      ts_list.count((x.size(), x.dtype)),
                      np.prod(np.array(x.size()))
                      * get_mem_space(x.dtype)
                      / 1024**2,
                      x.dtype,
                  )
                  for x in self.get_tensors()
              }
              for t, s, n, m, data_type in (
                  new_tensor_sizes - self.last_tensor_sizes
              ):
                  f.write(
                      f"+ | {str(n)} * Size:{str(s):<20} | Memory: {str(m * n)[:6]} M | {str(t):<20} | {data_type}\n"
                  )
              for t, s, n, m, data_type in (
                  self.last_tensor_sizes - new_tensor_sizes
              ):
                  f.write(
                      f"- | {str(n)} * Size:{str(s):<20} | Memory: {str(m * n)[:6]} M | {str(t):<20} | {data_type}\n"
                  )
  
              self.last_tensor_sizes = new_tensor_sizes
  
          f.write(
              f"\nAt {where_str:<50}"
              f" Total Tensor Used Memory:{self.get_tensor_usage():<7.1f}Mb"
              f" Total Allocated Memory:{self.get_allocate_usage():<7.1f}Mb\n\n"
          )
  
file_path: h2ogpt/models/gpu_mem_track.py
imports: import gc
  import datetime
  import inspect
  import torch
  import numpy
  import contextlib, sys
label_desc: Use image node_id 7 for calling the MemTracker obj's underlying member method code with example usage: obj.track() without return types