class_docstr: A Context that captures RunMetadata and performs profiling.
  
  ```python
    # Trace steps 100~200, profile at [150, 200] and dump profile at 200.
    with profile_context.ProfileContext('/tmp/train_dir',
                                        trace_steps=range(100, 200, 3),
                                        dump_steps=[200]) as pctx:
      opts = tf.profiler.ProfileOptionBuilder.time_and_memory()
      pctx.add_auto_profiling('op', opts, [150, 200])
      train_loop().
  
    # Tracing only.
    with profile_context.tfprof.ProfileContext('/tmp/train_dir') as pctx:
      # Run train/eval loop for at least few hundred steps. Profiles will be
      # dumped to train_dir. Use web UI or command line to do profiling.
      train_loop().
  
    # When session object is available, do explicit trace, profile and dump.
    with profile_context.ProfileContext('/tmp/train_dir',
                                        trace_steps=[],
                                        dump_steps=[]) as pctx:
      opts = tf.profiler.ProfileOptionBuilder.time_and_memory()
      pctx.trace_next_step()
      _ = session.run(train_op)
      pctx.profiler.profile_operations(options=opts)
  ```
  
  Args:
    profile_dir: Directory to store profiles.
    trace_steps: A list of session run steps to trace. If None, use
        pre-defined steps.
    dump_steps: A list of steps to dump the profile to `profile_dir`. If None,
        use pre-defined steps.
    enabled: If false, everything is disabled with minimal overhead. It allows
        user to only enable profiling when needed.
    debug: If true, also dumps the raw trace RunMetadata text file to
        profile_dir. And print debugging message. Useful for bug report.
code: def __init__(
      self,
      profile_dir,
      trace_steps=None,
      dump_steps=None,
      enabled=True,
      debug=False,
  ):
      self._enabled = enabled
      if not self._enabled:
          return
  
      self._debug = debug
      if not profile_dir:
          raise ValueError("Must have a directory for profile.\n")
      self._profiler_dir = profile_dir
  
      if trace_steps is None:
          self._trace_steps = set()
          self._auto_tracing = True
      else:
          if len(trace_steps) > MAX_TRACED_STEPS:
              raise ValueError(
                  "Only support tracing up to 100 steps.\n"
              )
          self._trace_steps = set(trace_steps[:])
          self._auto_tracing = False
  
      if dump_steps is None:
          self._dump_steps = set([MAX_TRACED_STEPS])
      else:
          self._dump_steps = set(dump_steps[:])
  
      self._rng = random.Random(111)
      self._fetched = set()
      self._slow_path_steps = self._dump_steps | self._trace_steps
      self._trace_next_step = False
      self._dump_next_step = False
      self._step = 0
      self._traced_steps = 0
      self._auto_profiles = []
      self._profiler = None
      self._views = {}
      self._lock = threading.Lock()
  
imports: import contextlib
  import os
  import random
  import sys
  import threading
  from tensorflow.core.protobuf import config_pb2
  from tensorflow.python.client import session
  from tensorflow.python.framework import errors
  from tensorflow.python.framework import ops
  from tensorflow.python.platform import gfile
  from tensorflow.python.profiler import model_analyzer
  from tensorflow.python.util import _pywrap_tfprof
  from tensorflow.python.util import compat
label_desc: Use image node_id 1 to create a new ProfileContext object from inherited base classes: object with example: obj = ProfileContext(profile_dir, trace_steps, dump_steps, enabled, debug)