class_docstr: Mark function calls with ranges using NVTX/rocTX. This object can be
  used either as a decorator or a context manager.
  
  When used as a decorator, the decorated function calls are marked as
  ranges:
  
  >>> from cupyx.profiler import time_range
  >>> @time_range()
  ... def function_to_profile():
  ...     pass
  
  When used as a context manager, it describes the enclosed block as a nested
  range:
  
  >>> from cupyx.profiler import time_range
  >>> with time_range('some range in green', color_id=0):
  ...    # do something you want to measure
  ...    pass
  
  The marked ranges are visible in the profiler (such as nvvp, nsys-ui, etc)
  timeline.
  
  Args:
      message (str): Name of a range. When used as a decorator, the default
          is ``func.__name__``.
      color_id: range color ID
      argb_color: range color in ARGB (e.g. 0xFF00FF00 for green)
      sync (bool): If ``True``, waits for completion of all outstanding
          processing on GPU before calling :func:`cupy.cuda.nvtx.RangePush()`
          or :func:`cupy.cuda.nvtx.RangePop()`
  
  .. seealso:: :func:`cupy.cuda.nvtx.RangePush`,
      :func:`cupy.cuda.nvtx.RangePop`
code: def __init__(
      self, message=None, color_id=None, argb_color=None, sync=False
  ):
      if not cuda.nvtx.available:
          raise RuntimeError("nvtx is not installed")
  
      if color_id is not None and argb_color is not None:
          raise ValueError(
              "Only either color_id or argb_color can be specified"
          )
      self.message = message
      self.color_id = color_id if color_id is not None else -1
      self.argb_color = argb_color
      self.sync = sync
  
file_path: cupy/cupyx/profiler/_time_range.py
imports: import functools
  from cupy import cuda
  from cupy_backends.cuda.api import runtime
label_desc: Use image node_id 1 to create a new time_range object  with example: obj = time_range(message, color_id, argb_color, sync)