code: def assert_index_equal(
      left,
      right,
      exact="equiv",
      check_names: bool = True,
      check_less_precise: Union[bool, int] = False,
      check_exact: bool = True,
      check_categorical: bool = True,
      check_order: bool = True,
      rtol: float = 1e-5,
      atol: float = 1e-8,
      obj: str = "Index",
  ):
      """
      Check that left and right Index are equal
  
      This function is intended to compare two Index and output
      any differences. Additional parameters allow varying the strictness
      of the equality checks performed.
  
      Parameters
      ----------
      left : Index
          left Index to compare
      right : Index
          right Index to compare
      exact : bool or {'equiv'}, default 'equiv'
          Whether to check the Index class, dtype and inferred_type
          are identical. If 'equiv', then RangeIndex can be substituted
          for Int8Index, Int16Index, Int32Index, Int64Index as well.
      check_names : bool, default True
          Whether to check the names attribute.
      check_less_precise : bool or int, default False
          Not yet supported
      check_exact : bool, default False
          Whether to compare number exactly.
      check_categorical : bool, default True
          Whether to compare internal Categorical exactly.
      check_order : bool, default True
          Whether to compare the order of index entries as
          well as their values.
          If True, both indexes must contain the same elements,
          in the same order.
          If False, both indexes must contain the same elements,
          but in any order.
      rtol : float, default 1e-5
          Relative tolerance. Only used when `check_exact` is False.
      atol : float, default 1e-8
          Absolute tolerance. Only used when `check_exact` is False.
      obj : str, default 'Index'
          Specify object name being compared, internally used to
          show appropriate assertion message.
  
      Examples
      --------
      >>> import cudf
      >>> id1 = cudf.Index([1, 2, 3, 4])
      >>> id2 = cudf.Index([1, 2, 3, 5])
      >>> cudf.testing.assert_index_equal(id1, id2)
      ......
      ......
      AssertionError: ColumnBase are different
      <BLANKLINE>
      values are different (25.0 %)
      [left]:  [1 2 3 4]
      [right]: [1 2 3 5]
  
      >>> id2 = cudf.Index([1, 2, 3, 4], name="b")
      >>> cudf.testing.assert_index_equal(id1, id2)
      ......
      ......
      AssertionError: Index are different
      <BLANKLINE>
      name mismatch
      [left]:  a
      [right]: b
  
      This will pass without any hitch:
  
      >>> id2 = cudf.Index([1, 2, 3, 4], name="a")
      >>> cudf.testing.assert_index_equal(id1, id2)
      """
  
      # instance validation
      _check_isinstance(left, right, cudf.BaseIndex)
  
      _check_types(
          left,
          right,
          exact=exact,
          check_categorical=check_categorical,
          obj=obj,
      )
  
      if len(left) != len(right):
          raise_assert_detail(
              obj,
              "lengths are different",
              f"{len(left)}",
              f"{len(right)}",
          )
  
      # If order doesn't matter then sort the index entries
      if not check_order:
          left = left.sort_values()
          right = right.sort_values()
  
      if isinstance(left, cudf.MultiIndex):
          if left.nlevels != right.nlevels:
              raise AssertionError(
                  "Number of levels mismatch, "
                  f"left has {left.nlevels} levels and right has {right.nlevels}"
              )
  
          for level in range(left.nlevels):
              llevel = cudf.Index(
                  left._columns[level], name=left.names[level]
              )
              rlevel = cudf.Index(
                  right._columns[level], name=right.names[level]
              )
              mul_obj = f"MultiIndex level [{level}]"
              assert_index_equal(
                  llevel,
                  rlevel,
                  exact=check_exact,
                  check_names=check_names,
                  check_exact=check_exact,
                  check_less_precise=check_less_precise,
                  check_order=check_order,
                  rtol=rtol,
                  atol=atol,
                  obj=mul_obj,
              )
          return
      assert_column_equal(
          left._columns[0],
          right._columns[0],
          check_dtype=exact,
          check_exact=check_exact,
          check_categorical=check_categorical,
          obj=obj,
      )
  
      # metadata comparison
      if check_names and (left.name != right.name):
          raise_assert_detail(
              obj, "name mismatch", f"{left.name}", f"{right.name}"
          )
  
file_path: cudf/python/cudf/cudf/testing/testing.py
imports: from __future__ import annotations
  from typing import Union
  import cupy
  import numpy
  import pandas
  import cudf
  from cudf._lib.unary import is_nan
  from cudf.api.types import is_categorical_dtype, is_numeric_dtype, is_string_dtype
  from cudf.core.missing import NA, NaT
label_desc: Use image node_id 7 for calling a global function with example usage: assert_index_equal(left, right, exact, check_names, check_less_precise, check_exact, check_categorical, check_order, rtol, atol, obj) without return types